Commit 106230fe authored by wanglei's avatar wanglei

初始化

parent 65e6c8bc
Pipeline #1234 canceled with stages
target/
build/
lint.xml
bin/
gen/
.settings
.project
.classpath
out
gen-external-apklibs/
classes/
# Local configuration file (sdk path, etc)
local.properties
# Android Studio
.idea/
*/out
!*/build/apk/
*/production/
*.iws
*.ipr
*.iml
*~
*.swp
# gradle
.gradle
.DS_Store
\ No newline at end of file
## 2.8.1 (2017-11-11)
* Fix bug with rendering `PDFView` in Android Studio Layout Editor
## 2.8.0 (2017-10-31)
* Add handling of invalid pages, inspired by pull request #433. Exception on page opening crashed application until now,
currently `OnPageErrorListener` set with `.onPageError()` is called. Invalid page color can be set using `.invalidPageColor()`
* Implement `canScrollVertically()` and `canScrollHorizontally()` methods to work e.g. with `SwipeRefreshLayout`
* Fix bug when `Configurator#load()` method was called before view has been measured, which resulted in empty canvas
## 2.7.0 (2017-08-30)
* Merge pull request by [owurman](https://github.com/owurman) with added OnTapListener
* Merge bugfix by [lzwandnju](https://github.com/lzwandnju) to prevent `ArithmeticException: divide by zero`
## 2.7.0-beta.1 (2017-07-05)
* Updates PdfiumAndroid to 1.7.0 which reduces memory usage about twice and improves performance by using RGB 565 format (when not using `pdfView.useBestQuality(true)`)
## 2.7.0-beta (2017-06-16)
* Update PdfiumAndroid to 1.6.1, which fixed font rendering (issue #253)
* Add `.spacing(int)` method to add spacing (in dp) between document pages
* Fix drawing with `.onDraw(onDrawListener)`
* Add `.onDrawAll(onDrawListener)` method to draw on all pages
* Add small rendering improvements
* Fix rendering when duplicated pages are passed to `.pages(..)`
## 2.6.1 (2017-06-08)
* Fix disappearing scroll handle
## 2.6.0 (2017-06-04)
* Fix fling on single-page documents
* Greatly improve overall fling experience
## 2.5.1 (2017-04-08)
* Temporarily downgrade PdfiumAndroid until #253 will be fixed
## 2.5.0 (2017-03-23)
* Update PdfiumAndroid to 1.6.0, which is based on newest Pdfium from Android 7.1.1. It should fix many rendering and fonts problems
* Add method `pdfView.fitToWidth()`, which called in `OnRenderListener.onInitiallyRendered()` will fit document to width of the screen (inspired by [1stmetro](https://github.com/1stmetro))
* Add change from pull request by [isanwenyu](https://github.com/isanwenyu) to get rid of rare IllegalArgumentException while rendering
* Add `OnRenderListener`, that will be called once, right before document is drawn on the screen
* Add `Configurator.enableAntialiasing()` to improve rendering on low-res screen a little bit (as suggested by [majkimester](majkimester))
* Modify engine to not block UI when big documents are loaded
* Change `Constants` interface and inner interfaces to static public classes, to allow modifying core config values
## 2.4.0 (2016-12-30)
* Merge pull request by [hansinator85](https://github.com/hansinator85) which allows to enable/disable rendering during scale
* Make rendering during scale disabled by default (looks better)
* Merge pull request by [cesquivias](https://github.com/cesquivias) which replaces RenderingAsyncTask with Handler to simply code and work with testing frameworks
## 2.3.0 (2016-11-19)
* Add mechanism for providing documents from different sources - more info in README
* Update PdfiumAndroid to 1.5.0
* Thanks to document sources and PdfiumAndroid update, in-memory documents are supported
* Fix not working OnClickListener on PDFView
* **com.github.barteksc.exception.FileNotFoundException** is deprecated and all usages was removed.
All exceptions are delivered to old Configurator#onError() listener.
## 2.2.0 (2016-11-15)
* Merge pull request by [skarempudi](https://github.com/skarempudi) which fixes SDK 23 permission problems in sample app
* Merge pull request by skarempudi for showing info on phones without file manager
* Add feature from 1.x - canvas is set to drawable from View#getBackground()
## 2.1.0 (2016-09-16)
* fixed loading document from subfolder in assets directory
* fixed scroll handle NPE after document loading error (improvement of 2.0.3 fix)
* fixed incorrect scroll handle position with additional views in RelativeLayout
* improved cache usage and fixed bug with rendering when zooming
* if you are using custom scroll handle: scroll handle implementation changed a little bit, check DefaultScrollHandle source for details
## 2.0.3 (2016-08-30)
* Fix scroll handle NPE after document loading error
## 2.0.2 (2016-08-27)
* Fix exceptions caused by improperly finishing rendering task
## 2.0.1 (2016-08-16)
* Fix NPE when onDetachFromWindow is called
## 2.0.0 (2016-08-14)
* few API changes
* improved rendering speed and accuracy
* added continuous scroll - now it behaves like Adobe Reader and others
* added `fling` scroll gesture for velocity based scrolling
* added scroll handle as a replacement for scrollbar
### Changes in 2.0 API
* `Configurator#defaultPage(int)` and `PDFView#jumpTo(int)` now require page index (i.e. starting from 0)
* `OnPageChangeListener#onPageChanged(int, int)` is called with page index (i.e. starting from 0)
* removed scrollbar
* added scroll handle as a replacement for scrollbar, use with `Configurator#scrollHandle()`
* added `OnPageScrollListener` listener due to continuous scroll, register with `Configurator#onPageScroll()`
* default scroll direction is vertical, so `Configurator#swipeVertical()` was changed to `Configurator#swipeHorizontal()`
* removed minimap and mask configuration
## 1.4.0 (2016-07-25)
* Fix NPE and IndexOutOfBound bugs when rendering parts
* Merge pull request by [paulo-sato-daitan](https://github.com/paulo-sato-daitan) for disabling page change animation
* Merge pull request by [Miha-x64](https://github.com/Miha-x64) for drawing background if set on `PDFView`
## 1.3.0 (2016-07-13)
* update PdfiumAndroid to 1.4.0 with support for rendering annotations
* merge pull request by [usef](https://github.com/usef) for rendering annotations
## 1.2.0 (2016-07-11)
* update PdfiumAndroid to 1.3.1 with support for bookmarks, Table Of Contents and documents with password:
* added method `PDFView#getDocumentMeta()`, which returns document metadata
* added method `PDFView#getTableOfContents()`, which returns whole tree of bookmarks in PDF document
* added method `Configurator#password(String)`
* added horizontal mode to **ScrollBar** - use `ScrollBar#setHorizontal(true)` or `app:sb_horizontal="true"` in XML
* block interaction with `PDFView` when document is not loaded - prevent some exceptions
* fix `PDFView` exceptions in layout preview (edit mode)
## 1.1.2 (2016-06-27)
* update PdfiumAndroid to 1.1.0, which fixes displaying multiple `PDFView`s at the same time and few errors with loading PDF documents.
## 1.1.1 (2016-06-17)
* fixes bug with strange behavior when indices passed to `.pages()` don't start with `0`.
## 1.1.0 (2016-06-16)
* added method `pdfView.fromUri(Uri)` for opening files from content providers
* updated PdfiumAndroid to 1.0.3, which should fix bug with exception
* updated sample with demonstration of `fromUri()` method
* some minor fixes
## 1.0.0 (2016-06-06)
* Initial release
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.
/build
\ No newline at end of file
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
namespace 'com.shockwave.pdfium'
compileSdk 34
defaultConfig {
minSdk 24
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
ndk {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
// defaultConfig {
// externalNativeBuild {
// ndkBuild {
// arguments "-DANDROID_ABI=${defaultConfig.ndkAbbi}"
// }
// }
// }
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
// sourceSets {
// main {
// jni.srcDirs = []
// jniLibs.srcDirs = ['src/main/jniLibs']
// }
// }
sourceSets {
main {
jni.srcDirs = ['src/main/jni']
jniLibs.srcDirs = ['src/main/jni/lib']
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation("androidx.appcompat:appcompat:1.7.0")
implementation "androidx.core:core-ktx:$kotlin_version"
}
\ No newline at end of file
-keepclassmembers class * {
native <methods>;
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keepclassmembers class * {
native <methods>;
}
\ No newline at end of file
package com.shockwave.pdfium;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.shockwave.pdfium.test", appContext.getPackageName());
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>
\ No newline at end of file
package com.shockwave.pdfium;
import android.os.ParcelFileDescriptor;
import android.util.ArrayMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class PdfDocument {
public static class Meta {
String title;
String author;
String subject;
String keywords;
String creator;
String producer;
String creationDate;
String modDate;
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getSubject() {
return subject;
}
public String getKeywords() {
return keywords;
}
public String getCreator() {
return creator;
}
public String getProducer() {
return producer;
}
public String getCreationDate() {
return creationDate;
}
public String getModDate() {
return modDate;
}
}
public static class Bookmark {
private List<Bookmark> children = new ArrayList<>();
String title;
long pageIdx;
long mNativePtr;
public List<Bookmark> getChildren() {
return children;
}
public boolean hasChildren() {
return !children.isEmpty();
}
public String getTitle() {
return title;
}
public long getPageIdx() {
return pageIdx;
}
}
/*package*/ PdfDocument() {
}
/*package*/ long mNativeDocPtr;
/*package*/ ParcelFileDescriptor parcelFileDescriptor;
/*package*/ final Map<Integer, Long> mNativePagesPtr = new ArrayMap<>();
public boolean hasPage(int index) {
return mNativePagesPtr.containsKey(index);
}
}
package com.shockwave.pdfium;
import java.io.IOException;
public class PdfPasswordException extends IOException {
public PdfPasswordException() {
super();
}
public PdfPasswordException(String detailMessage) {
super(detailMessage);
}
}
package com.shockwave.pdfium;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.view.Surface;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class PdfiumCore {
private static final String TAG = PdfiumCore.class.getName();
static {
try {
System.loadLibrary("modpng");
System.loadLibrary("modft2");
System.loadLibrary("modpdfium");
System.loadLibrary("jniPdfium");
} catch (UnsatisfiedLinkError e) {
Log.e(TAG, "Native libraries failed to load - " + e);
}
}
public native long TestJniFun();
private native long nativeOpenDocument(int fd, String password);
private native long nativeOpenMemDocument(byte[] data, String password);
private native void nativeCloseDocument(long docPtr);
private native int nativeGetPageCount(long docPtr);
private native long nativeLoadPage(long docPtr, int pageIndex);
private native long[] nativeLoadPages(long docPtr, int fromIndex, int toIndex);
private native void nativeClosePage(long pagePtr);
private native void nativeClosePages(long[] pagesPtr);
private native int nativeGetPageWidthPixel(long pagePtr, int dpi);
private native int nativeGetPageHeightPixel(long pagePtr, int dpi);
private native int nativeGetPageWidthPoint(long pagePtr);
private native int nativeGetPageHeightPoint(long pagePtr);
//private native long nativeGetNativeWindow(Surface surface);
//private native void nativeRenderPage(long pagePtr, long nativeWindowPtr);
private native void nativeRenderPage(long pagePtr, Surface surface, int dpi,
int startX, int startY,
int drawSizeHor, int drawSizeVer,
boolean renderAnnot);
private native void nativeRenderPageBitmap(long pagePtr, Bitmap bitmap, int dpi,
int startX, int startY,
int drawSizeHor, int drawSizeVer,
boolean renderAnnot);
private native String nativeGetDocumentMetaText(long docPtr, String tag);
private native Long nativeGetFirstChildBookmark(long docPtr, Long bookmarkPtr);
private native Long nativeGetSiblingBookmark(long docPtr, long bookmarkPtr);
private native String nativeGetBookmarkTitle(long bookmarkPtr);
private native long nativeGetBookmarkDestIndex(long docPtr, long bookmarkPtr);
private static final Class FD_CLASS = FileDescriptor.class;
private static final String FD_FIELD_NAME = "descriptor";
private static Field mFdField = null;
private int mCurrentDpi;
/* synchronize native methods */
private static final Object lock = new Object();
public PdfiumCore(Context ctx) {
mCurrentDpi = ctx.getResources().getDisplayMetrics().densityDpi;
}
public static int getNumFd(ParcelFileDescriptor fdObj) {
try {
if (mFdField == null) {
mFdField = FD_CLASS.getDeclaredField(FD_FIELD_NAME);
mFdField.setAccessible(true);
}
return mFdField.getInt(fdObj.getFileDescriptor());
} catch (NoSuchFieldException e) {
e.printStackTrace();
return -1;
} catch (IllegalAccessException e) {
e.printStackTrace();
return -1;
}
}
public PdfDocument newDocument(ParcelFileDescriptor fd) throws IOException {
return newDocument(fd, null);
}
public PdfDocument newDocument(ParcelFileDescriptor fd, String password) throws IOException {
PdfDocument document = new PdfDocument();
document.parcelFileDescriptor = fd;
synchronized (lock) {
document.mNativeDocPtr = nativeOpenDocument(getNumFd(fd), password);
}
return document;
}
public PdfDocument newDocument(byte[] data) throws IOException {
return newDocument(data, null);
}
public PdfDocument newDocument(byte[] data, String password) throws IOException {
PdfDocument document = new PdfDocument();
synchronized (lock) {
document.mNativeDocPtr = nativeOpenMemDocument(data, password);
}
return document;
}
public int getPageCount(PdfDocument doc) {
synchronized (lock) {
return nativeGetPageCount(doc.mNativeDocPtr);
}
}
public long openPage(PdfDocument doc, int pageIndex) {
long pagePtr;
synchronized (lock) {
pagePtr = nativeLoadPage(doc.mNativeDocPtr, pageIndex);
doc.mNativePagesPtr.put(pageIndex, pagePtr);
return pagePtr;
}
}
public long[] openPage(PdfDocument doc, int fromIndex, int toIndex) {
long[] pagesPtr;
synchronized (lock) {
pagesPtr = nativeLoadPages(doc.mNativeDocPtr, fromIndex, toIndex);
int pageIndex = fromIndex;
for (long page : pagesPtr) {
if (pageIndex > toIndex) break;
doc.mNativePagesPtr.put(pageIndex, page);
pageIndex++;
}
return pagesPtr;
}
}
public int getPageWidth(PdfDocument doc, int index) {
synchronized (lock) {
Long pagePtr;
if ((pagePtr = doc.mNativePagesPtr.get(index)) != null) {
return nativeGetPageWidthPixel(pagePtr, mCurrentDpi);
}
return 0;
}
}
public int getPageHeight(PdfDocument doc, int index) {
synchronized (lock) {
Long pagePtr;
if ((pagePtr = doc.mNativePagesPtr.get(index)) != null) {
return nativeGetPageHeightPixel(pagePtr, mCurrentDpi);
}
return 0;
}
}
public int getPageWidthPoint(PdfDocument doc, int index) {
synchronized (lock) {
Long pagePtr;
if ((pagePtr = doc.mNativePagesPtr.get(index)) != null) {
return nativeGetPageWidthPoint(pagePtr);
}
return 0;
}
}
public int getPageHeightPoint(PdfDocument doc, int index) {
synchronized (lock) {
Long pagePtr;
if ((pagePtr = doc.mNativePagesPtr.get(index)) != null) {
return nativeGetPageHeightPoint(pagePtr);
}
return 0;
}
}
public void renderPage(PdfDocument doc, Surface surface, int pageIndex,
int startX, int startY, int drawSizeX, int drawSizeY) {
renderPage(doc, surface, pageIndex, startX, startY, drawSizeX, drawSizeY, false);
}
public void renderPage(PdfDocument doc, Surface surface, int pageIndex,
int startX, int startY, int drawSizeX, int drawSizeY,
boolean renderAnnot) {
synchronized (lock) {
try {
//nativeRenderPage(doc.mNativePagesPtr.get(pageIndex), surface, mCurrentDpi);
nativeRenderPage(doc.mNativePagesPtr.get(pageIndex), surface, mCurrentDpi,
startX, startY, drawSizeX, drawSizeY, renderAnnot);
} catch (NullPointerException e) {
Log.e(TAG, "mContext may be null");
e.printStackTrace();
} catch (Exception e) {
Log.e(TAG, "Exception throw from native");
e.printStackTrace();
}
}
}
public void renderPageBitmap(PdfDocument doc, Bitmap bitmap, int pageIndex,
int startX, int startY, int drawSizeX, int drawSizeY) {
renderPageBitmap(doc, bitmap, pageIndex, startX, startY, drawSizeX, drawSizeY, false);
}
public void renderPageBitmap(PdfDocument doc, Bitmap bitmap, int pageIndex,
int startX, int startY, int drawSizeX, int drawSizeY,
boolean renderAnnot) {
synchronized (lock) {
try {
nativeRenderPageBitmap(doc.mNativePagesPtr.get(pageIndex), bitmap, mCurrentDpi,
startX, startY, drawSizeX, drawSizeY, renderAnnot);
} catch (NullPointerException e) {
Log.e(TAG, "mContext may be null");
e.printStackTrace();
} catch (Exception e) {
Log.e(TAG, "Exception throw from native");
e.printStackTrace();
}
}
}
public void closeDocument(PdfDocument doc) {
synchronized (lock) {
for (Integer index : doc.mNativePagesPtr.keySet()) {
nativeClosePage(doc.mNativePagesPtr.get(index));
}
doc.mNativePagesPtr.clear();
nativeCloseDocument(doc.mNativeDocPtr);
if (doc.parcelFileDescriptor != null) { //if document was loaded from file
try {
doc.parcelFileDescriptor.close();
} catch (IOException e) {
/* ignore */
}
doc.parcelFileDescriptor = null;
}
}
}
public PdfDocument.Meta getDocumentMeta(PdfDocument doc) {
synchronized (lock) {
PdfDocument.Meta meta = new PdfDocument.Meta();
meta.title = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Title");
meta.author = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Author");
meta.subject = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Subject");
meta.keywords = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Keywords");
meta.creator = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Creator");
meta.producer = nativeGetDocumentMetaText(doc.mNativeDocPtr, "Producer");
meta.creationDate = nativeGetDocumentMetaText(doc.mNativeDocPtr, "CreationDate");
meta.modDate = nativeGetDocumentMetaText(doc.mNativeDocPtr, "ModDate");
return meta;
}
}
public List<PdfDocument.Bookmark> getTableOfContents(PdfDocument doc) {
synchronized (lock) {
List<PdfDocument.Bookmark> topLevel = new ArrayList<>();
Long first = nativeGetFirstChildBookmark(doc.mNativeDocPtr, null);
if (first != null) {
recursiveGetBookmark(topLevel, doc, first);
}
return topLevel;
}
}
private void recursiveGetBookmark(List<PdfDocument.Bookmark> tree, PdfDocument doc, long bookmarkPtr) {
PdfDocument.Bookmark bookmark = new PdfDocument.Bookmark();
bookmark.mNativePtr = bookmarkPtr;
bookmark.title = nativeGetBookmarkTitle(bookmarkPtr);
bookmark.pageIdx = nativeGetBookmarkDestIndex(doc.mNativeDocPtr, bookmarkPtr);
tree.add(bookmark);
Long child = nativeGetFirstChildBookmark(doc.mNativeDocPtr, bookmarkPtr);
if (child != null) {
recursiveGetBookmark(bookmark.getChildren(), doc, child);
}
Long sibling = nativeGetSiblingBookmark(doc.mNativeDocPtr, bookmarkPtr);
if (sibling != null) {
recursiveGetBookmark(tree, doc, sibling);
}
}
}
LOCAL_PATH := $(call my-dir)
#Prebuilt libraries
include $(CLEAR_VARS)
LOCAL_MODULE := aospPdfium
ARCH_PATH = $(TARGET_ARCH_ABI)
ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
ARCH_PATH = armeabi-v7a
endif
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
ARCH_PATH = arm64-v8a
endif
LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/$(ARCH_PATH)/libmodpdfium.so
include $(PREBUILT_SHARED_LIBRARY)
#libmodft2
include $(CLEAR_VARS)
LOCAL_MODULE := libmodft2
LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/$(ARCH_PATH)/libmodft2.so
include $(PREBUILT_SHARED_LIBRARY)
#libmodpng
include $(CLEAR_VARS)
LOCAL_MODULE := libmodpng
LOCAL_SRC_FILES := $(LOCAL_PATH)/lib/$(ARCH_PATH)/libmodpng.so
include $(PREBUILT_SHARED_LIBRARY)
#Main JNI library
include $(CLEAR_VARS)
LOCAL_MODULE := jniPdfium
LOCAL_CFLAGS += -DHAVE_PTHREADS
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SHARED_LIBRARIES += aospPdfium
LOCAL_LDLIBS += -llog -landroid -ljnigraphics
LOCAL_SRC_FILES := $(LOCAL_PATH)/src/mainJNILib.cpp
include $(BUILD_SHARED_LIBRARY)
# APP_STL := gnustl_static
APP_STL := c++_static
APP_CPPFLAGS += -fexceptions
#For ANativeWindow support
APP_PLATFORM = android-9
APP_ABI := armeabi \
armeabi-v7a \
arm64-v8a \
mips \
x86 \
x86_64
\ No newline at end of file
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_DATAAVAIL_H_
#define PUBLIC_FPDF_DATAAVAIL_H_
#include <stddef.h> // For size_t.
#include "fpdfview.h"
#define PDF_LINEARIZATION_UNKNOWN -1
#define PDF_NOT_LINEARIZED 0
#define PDF_LINEARIZED 1
#define PDF_DATA_ERROR -1
#define PDF_DATA_NOTAVAIL 0
#define PDF_DATA_AVAIL 1
#define PDF_FORM_ERROR -1
#define PDF_FORM_NOTAVAIL 0
#define PDF_FORM_AVAIL 1
#define PDF_FORM_NOTEXIST 2
#ifdef __cplusplus
extern "C" {
#endif
/**
* Interface: FX_FILEAVAIL
* Interface for checking whether the section of the file is available.
*/
typedef struct _FX_FILEAVAIL {
/**
* Version number of the interface. Currently must be 1.
*/
int version;
/**
* Method: IsDataAvail
* Report whether the specified data section is available. A section is
* available only if all bytes in the section is available.
* Interface Version:
* 1
* Implementation Required:
* Yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* offset - The offset of the data section in the file.
* size - The size of the data section
* Return Value:
* true means the specified data section is available.
* Comments:
* Called by Foxit SDK to check whether the data section is ready.
*/
FPDF_BOOL (*IsDataAvail)(struct _FX_FILEAVAIL* pThis, size_t offset, size_t size);
} FX_FILEAVAIL;
typedef void* FPDF_AVAIL;
/**
* Function: FPDFAvail_Create
* Create a document availability provider.
*
* Parameters:
* file_avail - Pointer to file availability interface to check
* availability of file data.
* file - Pointer to a file access interface for reading data
* from file.
* Return value:
* A handle to the document availability provider. NULL for error.
* Comments:
* Application must call FPDFAvail_Destroy when done with the
* availability provider.
*/
DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail,
FPDF_FILEACCESS* file);
/**
* Function: FPDFAvail_Destroy
* Destroy a document availibity provider.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* Return Value:
* None.
*/
DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail);
/**
* Interface: FX_DOWNLOADHINTS
* Download hints interface. Used to receive hints for further
* downloading.
*/
typedef struct _FX_DOWNLOADHINTS {
/**
* Version number of the interface. Currently must be 1.
*/
int version;
/**
* Method: AddSegment
* Add a section to be downloaded.
* Interface Version:
* 1
* Implementation Required:
* Yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* offset - The offset of the hint reported to be downloaded.
* size - The size of the hint reported to be downloaded.
* Return Value:
* None.
* Comments:
* Called by Foxit SDK to report some downloading hints for download
* manager.
* The position and size of section may be not accurate, part of the
* section might be already available.
* The download manager must deal with that to maximize download
* efficiency.
*/
void (*AddSegment)(struct _FX_DOWNLOADHINTS* pThis,
size_t offset,
size_t size);
} FX_DOWNLOADHINTS;
/**
* Function: FPDFAvail_IsDocAvail
* Check whether the document is ready for loading, if not, get
* download hints.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* hints - Pointer to a download hints interface, receiving
* generated hints
* Return value:
* PDF_DATA_ERROR: A common error is returned. It can't tell
* whehter data are availabe or not.
* PDF_DATA_NOTAVAIL: Data are not yet available.
* PDF_DATA_AVAIL: Data are available.
* Comments:
* Applications should call this function whenever new data arrived,
* and process all the generated download hints if any, until the
* function returns PDF_DATA_ERROR or PDF_DATA_AVAIL. Then
* applications can call FPDFAvail_GetDocument() to get a document
* handle.
*/
DLLEXPORT int STDCALL
FPDFAvail_IsDocAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS* hints);
/**
* Function: FPDFAvail_GetDocument
* Get document from the availability provider.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* password - Optional password for decrypting the PDF file.
* Return value:
* Handle to the document.
* Comments:
* After FPDFAvail_IsDocAvail() returns TRUE, the application should
* call this function to
* get the document handle. To close the document, use
* FPDF_CloseDocument function.
*/
DLLEXPORT FPDF_DOCUMENT STDCALL FPDFAvail_GetDocument(FPDF_AVAIL avail,
FPDF_BYTESTRING password);
/**
* Function: FPDFAvail_GetFirstPageNum
* Get page number for the first available page in a linearized PDF
*
* Parameters:
* doc - A document handle returned by FPDFAvail_GetDocument
* Return Value:
* Zero-based index for the first available page.
* Comments:
* For most linearized PDFs, the first available page would be just the
* first page, however,
* some PDFs might make other page to be the first available page.
* For non-linearized PDF, this function will always return zero.
*/
DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc);
/**
* Function: FPDFAvail_IsPageAvail
* Check whether a page is ready for loading, if not, get download
* hints.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* page_index - Index number of the page. 0 for the first page.
* hints - Pointer to a download hints interface, receiving
* generated hints
* Return value:
* PDF_DATA_ERROR: A common error is returned. It can't tell
* whehter data are availabe or not.
* PDF_DATA_NOTAVAIL: Data are not yet available.
* PDF_DATA_AVAIL: Data are available.
* Comments:
* This function can be called only after FPDFAvail_GetDocument is
* called. Applications should call this function whenever new data
* arrived and process all the generated download hints if any, until
* this function returns PDF_DATA_ERROR or PDF_DATA_AVAIL. Then
* applications can perform page loading.
*/
DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail,
int page_index,
FX_DOWNLOADHINTS* hints);
/**
* Function: FPDFAvail_ISFormAvail
* Check whether Form data is ready for init, if not, get download
* hints.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* hints - Pointer to a download hints interface, receiving
* generated hints
* Return value:
* PDF_FORM_ERROR - A common eror, in general incorrect parameters,
* like 'hints' is nullptr.
* PDF_FORM_NOTAVAIL - data not available
* PDF_FORM_AVAIL - data available
* PDF_FORM_NOTEXIST - no form data
* Comments:
* This function can be called only after FPDFAvail_GetDocument is
* called.
* The application should call this function whenever new data arrived,
* and process all the
* generated download hints if any, until the function returns non-zero
* value. Then the
* application can perform page loading. Recommend to call
* FPDFDOC_InitFormFillEnvironment
* after the function returns non-zero value.
*/
DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail,
FX_DOWNLOADHINTS* hints);
/**
* Function: FPDFAvail_IsLinearized
* To check whether a document is Linearized PDF file.
*
* Parameters:
* avail - Handle to document availability provider returned by
* FPDFAvail_Create
* Return value:
* PDF_LINEARIZED is a linearize file.
* PDF_NOT_LINEARIZED is not a linearize file.
* PDF_LINEARIZATION_UNKNOWN doesn't know whether the file is a
*linearize file.
*
* Comments:
* It return PDF_LINEARIZED or PDF_NOT_LINEARIZED as soon as
* we have first 1K data. If the file's size less than 1K, it returns
* PDF_LINEARIZATION_UNKNOWN because there is not enough information to
* tell whether a PDF file is a linearized file or not.
*
*/
DLLEXPORT int STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_DATAAVAIL_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_DOC_H_
#define PUBLIC_FPDF_DOC_H_
#include "fpdfview.h"
// Exported Functions
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDFBookmark_GetFirstChild
// Get the first child of a bookmark item, or the first top level
// bookmark item.
// Parameters:
// document - Handle to the document. Returned by
// FPDF_LoadDocument or FPDF_LoadMemDocument.
// bookmark - Handle to the current bookmark. Can be NULL if you
// want to get the first top level item.
// Return value:
// Handle to the first child or top level bookmark item. NULL if no
// child or top level bookmark found.
//
DLLEXPORT FPDF_BOOKMARK STDCALL
FPDFBookmark_GetFirstChild(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark);
// Function: FPDFBookmark_GetNextSibling
// Get next bookmark item at the same level.
// Parameters:
// document - Handle to the document. Returned by
// FPDF_LoadDocument or FPDF_LoadMemDocument.
// bookmark - Handle to the current bookmark. Cannot be NULL.
// Return value:
// Handle to the next bookmark item at the same level. NULL if this is
// the last bookmark at this level.
//
DLLEXPORT FPDF_BOOKMARK STDCALL
FPDFBookmark_GetNextSibling(FPDF_DOCUMENT document, FPDF_BOOKMARK bookmark);
// Function: FPDFBookmark_GetTitle
// Get title of a bookmark.
// Parameters:
// bookmark - Handle to the bookmark.
// buffer - Buffer for the title. Can be NULL.
// buflen - The length of the buffer in bytes. Can be 0.
// Return value:
// Number of bytes the title consumes, including trailing zeros.
// Comments:
// Regardless of the platform, the title is always in UTF-16LE
// encoding. That means the buffer
// can be treated as an array of WORD (on Intel and compatible CPUs),
// each WORD representing the Unicode of
// a character(some special Unicode may take 2 WORDs).The string is
// followed by two bytes of zero
// indicating the end of the string.
//
// The return value always indicates the number of bytes required for
// the buffer, even if no buffer is specified
// or the buffer size is less then required. In these cases, the buffer
// will not be modified.
//
DLLEXPORT unsigned long STDCALL FPDFBookmark_GetTitle(FPDF_BOOKMARK bookmark,
void* buffer,
unsigned long buflen);
// Function: FPDFBookmark_Find
// Find a bookmark in the document, using the bookmark title.
// Parameters:
// document - Handle to the document. Returned by
// FPDF_LoadDocument or FPDF_LoadMemDocument.
// title - The UTF-16LE encoded Unicode string for the bookmark
// title to be searched. Can't be NULL.
// Return value:
// Handle to the found bookmark item. NULL if the title can't be found.
// Comments:
// It always returns the first found bookmark if more than one
// bookmarks have the same title.
//
DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document,
FPDF_WIDESTRING title);
// Function: FPDFBookmark_GetDest
// Get the destination associated with a bookmark item.
// Parameters:
// document - Handle to the document.
// bookmark - Handle to the bookmark.
// Return value:
// Handle to the destination data. NULL if no destination is associated
// with this bookmark.
//
DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document,
FPDF_BOOKMARK bookmark);
// Function: FPDFBookmark_GetAction
// Get the action associated with a bookmark item.
// Parameters:
// bookmark - Handle to the bookmark.
// Return value:
// Handle to the action data. NULL if no action is associated with this
// bookmark. In this case, the
// application should try FPDFBookmark_GetDest.
//
DLLEXPORT FPDF_ACTION STDCALL FPDFBookmark_GetAction(FPDF_BOOKMARK bookmark);
#define PDFACTION_UNSUPPORTED 0 // Unsupported action type.
#define PDFACTION_GOTO 1 // Go to a destination within current document.
#define PDFACTION_REMOTEGOTO 2 // Go to a destination within another document.
#define PDFACTION_URI 3 // Universal Resource Identifier, including web
// pages and other Internet based resources.
#define PDFACTION_LAUNCH 4 // Launch an application or open a file.
// Function: FPDFAction_GetType
// Get type of an action.
// Parameters:
// action - Handle to the action.
// Return value:
// A type number as defined above.
//
DLLEXPORT unsigned long STDCALL FPDFAction_GetType(FPDF_ACTION action);
// Function: FPDFAction_GetDest
// Get destination of an action.
// Parameters:
// document - Handle to the document.
// action - Handle to the action. It must be a GOTO or
// REMOTEGOTO action.
// Return value:
// Handle to the destination data.
// Comments:
// In case of remote goto action, the application should first use
// FPDFAction_GetFilePath to
// get file path, then load that particular document, and use its
// document handle to call this
// function.
//
DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document,
FPDF_ACTION action);
// Function: FPDFAction_GetFilePath
// Get file path of a remote goto action.
// Parameters:
// action - Handle to the action. Must be a REMOTEGOTO or
// LAUNCH action.
// buffer - A buffer for output the path string. Can be NULL.
// buflen - The length of the buffer, number of bytes. Can be 0.
// Return value:
// Number of bytes the file path consumes, including trailing zero.
//
// Comments:
// The file path is UTF-8 encoded. The return value is the number of
// bytes required for the buffer, even when there is no buffer
// specified, or the buffer size is less then required. In this case,
// the buffer will not be modified.
//
DLLEXPORT unsigned long STDCALL
FPDFAction_GetFilePath(FPDF_ACTION action, void* buffer, unsigned long buflen);
// Function: FPDFAction_GetURIPath
// Get URI path of a URI action.
// Parameters:
// document - Handle to the document.
// action - Handle to the action. Must be a URI action.
// buffer - A buffer for output the path string. Can be NULL.
// buflen - The length of the buffer, number of bytes. Can be 0.
// Return value:
// Number of bytes the URI path consumes, including trailing zeros.
// Comments:
// The URI path is always encoded in 7-bit ASCII.
//
// The return value is the number of bytes required for the buffer,
// even when there is no buffer specified, or the buffer size is less
// then required. In this case, the buffer will not be modified.
//
DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document,
FPDF_ACTION action,
void* buffer,
unsigned long buflen);
// Function: FPDFDest_GetPageIndex
// Get page index of a destination.
// Parameters:
// document - Handle to the document.
// dest - Handle to the destination.
// Return value:
// The page index. Starting from 0 for the first page.
//
DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document,
FPDF_DEST dest);
// Function: FPDFLink_GetLinkAtPoint
// Find a link at specified point on a document page.
// Parameters:
// page - Handle to the document page.
// x - The x coordinate of the point, specified in page
// coordinate system.
// y - The y coordinate of the point, specified in page
// coordinate system.
// Return value:
// Handle to the link. NULL if no link found at that point.
// Comments:
// The point coordinates are specified in page coordinate system. You can
// convert coordinates from screen system to page system using
// FPDF_DeviceToPage().
//
DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page,
double x,
double y);
// Function: FPDFLink_GetLinkZOrderAtPoint
// Find the z-order of a link at specified point on a document page.
// Parameters:
// page - Handle to the document page.
// x - The x coordinate of the point, specified in page
// coordinate system.
// y - The y coordinate of the point, specified in page
// coordinate system.
// Return value:
// Z-order of the link, or -1 if no link found at that point.
// Higher numbers are closer to the front.
// Comments:
// The point coordinates are specified in page coordinate system. You can
// convert coordinates from screen system to page system using
// FPDF_DeviceToPage().
//
DLLEXPORT int STDCALL
FPDFLink_GetLinkZOrderAtPoint(FPDF_PAGE page, double x, double y);
// Function: FPDFLink_GetDest
// Get destination info of a link.
// Parameters:
// document - Handle to the document.
// link - Handle to the link. Returned by
// FPDFLink_GetLinkAtPoint.
// Return value:
// Handle to the destination. NULL if there is no destination
// associated with the link, in this case
// the application should try FPDFLink_GetAction.
//
DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document,
FPDF_LINK link);
// Function: FPDFLink_GetAction
// Get action info of a link.
// Parameters:
// link - Handle to the link.
// Return value:
// Handle to the action. NULL if there is no action associated with the
// link.
//
DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK link);
// Function: FPDFLink_Enumerate
// This function would enumerate all the link annotations in a single
// PDF page.
// Parameters:
// page[in] - Handle to the page.
// startPos[in,out] - The start position to enumerate the link
// annotations, which should be specified to start from
// - 0 for the first call, and would receive the
// next position for enumerating to start from.
// linkAnnot[out] - Receive the link handle.
// Return value:
// TRUE if succceed, else False;
//
DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page,
int* startPos,
FPDF_LINK* linkAnnot);
// Function: FPDFLink_GetAnnotRect
// Get the annotation rectangle. (Specified by the ¡°Rect¡± entry of
// annotation dictionary).
// Parameters:
// linkAnnot[in] - Handle to the link annotation.
// rect[out] - The annotation rect.
// Return value:
// TRUE if succceed, else False;
//
DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetAnnotRect(FPDF_LINK linkAnnot,
FS_RECTF* rect);
// Function: FPDFLink_CountQuadPoints
// Get the count of quadrilateral points to the link annotation.
// Parameters:
// linkAnnot[in] - Handle to the link annotation.
// Return value:
// The count of quadrilateral points.
//
DLLEXPORT int STDCALL FPDFLink_CountQuadPoints(FPDF_LINK linkAnnot);
/* _FS_DEF_STRUCTURE_QUADPOINTSF_ */
#ifndef _FS_DEF_STRUCTURE_QUADPOINTSF_
#define _FS_DEF_STRUCTURE_QUADPOINTSF_
typedef struct _FS_QUADPOINTSF {
FS_FLOAT x1;
FS_FLOAT y1;
FS_FLOAT x2;
FS_FLOAT y2;
FS_FLOAT x3;
FS_FLOAT y3;
FS_FLOAT x4;
FS_FLOAT y4;
} FS_QUADPOINTSF;
#endif /* _FS_DEF_STRUCTURE_QUADPOINTSF_ */
// Function: FPDFLink_GetQuadPoints
// Get the quadrilateral points for the specified index in the link
// annotation.
// Parameters:
// linkAnnot[in] - Handle to the link annotation.
// quadIndex[in] - The specified quad points index.
// quadPoints[out] - Receive the quadrilateral points.
// Return value:
// True if succeed, else False.
//
DLLEXPORT FPDF_BOOL STDCALL FPDFLink_GetQuadPoints(FPDF_LINK linkAnnot,
int quadIndex,
FS_QUADPOINTSF* quadPoints);
// Function: FPDF_GetMetaText
// Get a text from meta data of the document. Result is encoded in
// UTF-16LE.
// Parameters:
// doc - Handle to a document
// tag - The tag for the meta data. Currently, It can be
// "Title", "Author",
// "Subject", "Keywords", "Creator", "Producer",
// "CreationDate", or "ModDate".
// For detailed explanation of these tags and their
// respective values,
// please refer to PDF Reference 1.6, section 10.2.1,
// "Document Information Dictionary".
// buffer - A buffer for output the title. Can be NULL.
// buflen - The length of the buffer, number of bytes. Can be 0.
// Return value:
// Number of bytes the title consumes, including trailing zeros.
// Comments:
// No matter on what platform, the title is always output in UTF-16LE
// encoding, which means the buffer
// can be regarded as an array of WORD (on Intel and compatible CPUs),
// each WORD represent the Unicode of
// a character (some special Unicode may take 2 WORDs). The string is
// followed by two bytes of zero
// indicating end of the string.
//
// The return value always indicated number of bytes required for the
// buffer, even when there is
// no buffer specified, or the buffer size is less then required. In
// this case, the buffer will not
// be modified.
//
DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc,
FPDF_BYTESTRING tag,
void* buffer,
unsigned long buflen);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_DOC_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_EDIT_H_
#define PUBLIC_FPDF_EDIT_H_
#include <stdint.h>
#include "fpdfview.h"
// Define all types used in the SDK. Note they can be simply regarded as opaque
// pointers
// or long integer numbers.
#define FPDF_ARGB(a, r, g, b) \
((((uint32_t)(((uint8_t)(b) | ((FX_WORD)((uint8_t)(g)) << 8)) | \
(((FX_DWORD)(uint8_t)(r)) << 16)))) | \
(((FX_DWORD)(uint8_t)(a)) << 24))
#define FPDF_GetBValue(argb) ((uint8_t)(argb))
#define FPDF_GetGValue(argb) ((uint8_t)(((uint16_t)(argb)) >> 8))
#define FPDF_GetRValue(argb) ((uint8_t)((argb) >> 16))
#define FPDF_GetAValue(argb) ((uint8_t)((argb) >> 24))
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////
//
// Document functions
//
//////////////////////////////////////////////////////////////////////
// Function: FPDF_CreateNewDocument
// Create a new PDF document.
// Parameters:
// None.
// Return value:
// A handle to a document. If failed, NULL is returned.
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument();
//////////////////////////////////////////////////////////////////////
//
// Page functions
//
//////////////////////////////////////////////////////////////////////
// Function: FPDFPage_New
// Construct an empty page.
// Parameters:
// document - Handle to document. Returned by FPDF_LoadDocument
// and FPDF_CreateNewDocument.
// page_index - The index of a page.
// width - The page width.
// height - The page height.
// Return value:
// The handle to the page.
// Comments:
// Loaded page can be deleted by FPDFPage_Delete.
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document,
int page_index,
double width,
double height);
// Function: FPDFPage_Delete
// Delete a PDF page.
// Parameters:
// document - Handle to document. Returned by FPDF_LoadDocument
// and FPDF_CreateNewDocument.
// page_index - The index of a page.
// Return value:
// None.
DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index);
// Function: FPDFPage_GetRotation
// Get the page rotation. One of following values will be returned:
// 0(0), 1(90), 2(180), 3(270).
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// Return value:
// The PDF page rotation.
// Comment:
// The PDF page rotation is rotated clockwise.
DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page);
// Function: FPDFPage_SetRotation
// Set page rotation. One of following values will be set: 0(0), 1(90),
// 2(180), 3(270).
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// rotate - The value of the PDF page rotation.
// Return value:
// None.
// Comment:
// The PDF page rotation is rotated clockwise.
//
DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate);
// Function: FPDFPage_InsertObject
// Insert an object to the page. The page object is automatically
// freed.
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// page_obj - Handle to a page object. Returned by
// FPDFPageObj_NewTextObj,FPDFPageObj_NewTextObjEx and
// FPDFPageObj_NewPathObj.
// Return value:
// None.
DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page,
FPDF_PAGEOBJECT page_obj);
// Function: FPDFPage_CountObject
// Get number of page objects inside the page.
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// Return value:
// The number of the page object.
DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page);
// Function: FPDFPage_GetObject
// Get page object by index.
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// index - The index of a page object.
// Return value:
// The handle of the page object. Null for failed.
DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index);
// Function: FPDFPage_HasTransparency
// Check that whether the content of specified PDF page contains
// transparency.
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// Return value:
// TRUE means that the PDF page does contains transparency.
// Otherwise, returns FALSE.
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page);
// Function: FPDFPage_GenerateContent
// Generate PDF Page content.
// Parameters:
// page - Handle to a page. Returned by FPDFPage_New or
// FPDF_LoadPage.
// Return value:
// True if successful, false otherwise.
// Comment:
// Before you save the page to a file, or reload the page, you must
// call the FPDFPage_GenerateContent function.
// Or the changed information will be lost.
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page);
//////////////////////////////////////////////////////////////////////
//
// Page Object functions
//
//////////////////////////////////////////////////////////////////////
// Function: FPDFPageObj_HasTransparency
// Check that whether the specified PDF page object contains
// transparency.
// Parameters:
// pageObject - Handle to a page object.
// Return value:
// TRUE means that the PDF page object does contains transparency.
// Otherwise, returns FALSE.
DLLEXPORT FPDF_BOOL STDCALL
FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObject);
// Function: FPDFPageObj_Transform
// Transform (scale, rotate, shear, move) page object.
// Parameters:
// page_object - Handle to a page object. Returned by
// FPDFPageObj_NewImageObj.
// a - The coefficient "a" of the matrix.
// b - The coefficient "b" of the matrix.
// c - The coefficient "c" of the matrix.
// d - The coefficient "d" of the matrix.
// e - The coefficient "e" of the matrix.
// f - The coefficient "f" of the matrix.
// Return value:
// None.
DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
double a,
double b,
double c,
double d,
double e,
double f);
// Function: FPDFPage_TransformAnnots
// Transform (scale, rotate, shear, move) all annots in a page.
// Parameters:
// page - Handle to a page.
// a - The coefficient "a" of the matrix.
// b - The coefficient "b" of the matrix.
// c - The coefficient "c" of the matrix.
// d - The coefficient "d" of the matrix.
// e - The coefficient "e" of the matrix.
// f - The coefficient "f" of the matrix.
// Return value:
// None.
DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
double a,
double b,
double c,
double d,
double e,
double f);
// The page object constants.
#define FPDF_PAGEOBJ_TEXT 1
#define FPDF_PAGEOBJ_PATH 2
#define FPDF_PAGEOBJ_IMAGE 3
#define FPDF_PAGEOBJ_SHADING 4
#define FPDF_PAGEOBJ_FORM 5
//////////////////////////////////////////////////////////////////////
//
// Image functions
//
//////////////////////////////////////////////////////////////////////
// Function: FPDFPageObj_NewImgeObj
// Create a new Image Object.
// Parameters:
// document - Handle to document. Returned by
// FPDF_LoadDocument or FPDF_CreateNewDocument function.
// Return Value:
// Handle of image object.
DLLEXPORT FPDF_PAGEOBJECT STDCALL
FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document);
// Function: FPDFImageObj_LoadJpegFile
// Load Image from a JPEG image file and then set it to an image
// object.
// Parameters:
// pages - Pointers to the start of all loaded pages, could
// be NULL.
// nCount - Number of pages, could be 0.
// image_object - Handle of image object returned by
// FPDFPageObj_NewImgeObj.
// fileAccess - The custom file access handler, which specifies
// the JPEG image file.
// Return Value:
// TRUE if successful, FALSE otherwise.
// Note:
// The image object might already has an associated image, which is
// shared and cached by the loaded pages, In this case, we need to
// clear the cache of image for all the loaded pages.
// Pass pages and count to this API to clear the image cache.
DLLEXPORT FPDF_BOOL STDCALL
FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages,
int nCount,
FPDF_PAGEOBJECT image_object,
FPDF_FILEACCESS* fileAccess);
// Function: FPDFImageObj_SetMatrix
// Set the matrix of an image object.
// Parameters:
// image_object - Handle of image object returned by
// FPDFPageObj_NewImgeObj.
// a - The coefficient "a" of the matrix.
// b - The coefficient "b" of the matrix.
// c - The coefficient "c" of the matrix.
// d - The coefficient "d" of the matrix.
// e - The coefficient "e" of the matrix.
// f - The coefficient "f" of the matrix.
// Return value:
// TRUE if successful, FALSE otherwise.
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
double a,
double b,
double c,
double d,
double e,
double f);
// Function: FPDFImageObj_SetBitmap
// Set the bitmap to an image object.
// Parameters:
// pages - Pointer's to the start of all loaded pages.
// nCount - Number of pages.
// image_object - Handle of image object returned by
// FPDFPageObj_NewImgeObj.
// bitmap - The handle of the bitmap which you want to set
// it to the image object.
// Return value:
// TRUE if successful, FALSE otherwise.
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,
int nCount,
FPDF_PAGEOBJECT image_object,
FPDF_BITMAP bitmap);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_EDIT_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_EXT_H_
#define PUBLIC_FPDF_EXT_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
// flags for type of unsupport object.
#define FPDF_UNSP_DOC_XFAFORM 1
#define FPDF_UNSP_DOC_PORTABLECOLLECTION 2
#define FPDF_UNSP_DOC_ATTACHMENT 3
#define FPDF_UNSP_DOC_SECURITY 4
#define FPDF_UNSP_DOC_SHAREDREVIEW 5
#define FPDF_UNSP_DOC_SHAREDFORM_ACROBAT 6
#define FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM 7
#define FPDF_UNSP_DOC_SHAREDFORM_EMAIL 8
#define FPDF_UNSP_ANNOT_3DANNOT 11
#define FPDF_UNSP_ANNOT_MOVIE 12
#define FPDF_UNSP_ANNOT_SOUND 13
#define FPDF_UNSP_ANNOT_SCREEN_MEDIA 14
#define FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA 15
#define FPDF_UNSP_ANNOT_ATTACHMENT 16
#define FPDF_UNSP_ANNOT_SIG 17
typedef struct _UNSUPPORT_INFO {
/**
* Version number of the interface. Currently must be 1.
**/
int version;
/**
* Method: FSDK_UnSupport_Handler
* UnSupport Object process handling function.
* Interface Version:
* 1
* Implementation Required:
* Yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* nType - The type of unsupportObject
* Return value:
* None.
* */
void (*FSDK_UnSupport_Handler)(struct _UNSUPPORT_INFO* pThis, int nType);
} UNSUPPORT_INFO;
/**
* Function: FSDK_SetUnSpObjProcessHandler
* Setup A UnSupport Object process handler for foxit sdk.
* Parameters:
* unsp_info - Pointer to a UNSUPPORT_INFO structure.
* Return Value:
* TRUE means successful. FALSE means fails.
**/
DLLEXPORT FPDF_BOOL STDCALL
FSDK_SetUnSpObjProcessHandler(UNSUPPORT_INFO* unsp_info);
// flags for page mode.
// Unknown value
#define PAGEMODE_UNKNOWN -1
// Neither document outline nor thumbnail images visible
#define PAGEMODE_USENONE 0
// Document outline visible
#define PAGEMODE_USEOUTLINES 1
// Thumbnial images visible
#define PAGEMODE_USETHUMBS 2
// Full-screen mode, with no menu bar, window controls, or any other window
// visible
#define PAGEMODE_FULLSCREEN 3
// Optional content group panel visible
#define PAGEMODE_USEOC 4
// Attachments panel visible
#define PAGEMODE_USEATTACHMENTS 5
/**
* Function: FPDFDoc_GetPageMode
* Get the document's PageMode(How the document should be displayed
*when opened)
* Parameters:
* doc - Handle to document. Returned by FPDF_LoadDocument
*function.
* Return Value:
* The flags for page mode.
**/
DLLEXPORT int FPDFDoc_GetPageMode(FPDF_DOCUMENT document);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_EXT_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_FLATTEN_H_
#define PUBLIC_FPDF_FLATTEN_H_
#include "fpdfview.h"
// Result codes.
#define FLATTEN_FAIL 0 // Flatten operation failed.
#define FLATTEN_SUCCESS 1 // Flatten operation succeed.
#define FLATTEN_NOTHINGTODO 2 // There is nothing to be flattened.
// Flags.
#define FLAT_NORMALDISPLAY 0
#define FLAT_PRINT 1
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDFPage_Flatten
// Make annotations and form fields become part of the page contents
// itself.
// Parameters:
// page - Handle to the page, as returned by FPDF_LoadPage().
// nFlag - Intended use of the flattened result: 0 for normal display,
// 1 for printing.
// Return value:
// Either FLATTEN_FAIL, FLATTEN_SUCCESS, or FLATTEN_NOTHINGTODO (see
// above).
// Comments:
// Currently, all failures return FLATTEN_FAIL, with no indication for
// the reason
// for the failure.
DLLEXPORT int STDCALL FPDFPage_Flatten(FPDF_PAGE page, int nFlag);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_FLATTEN_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_FORMFILL_H_
#define PUBLIC_FPDF_FORMFILL_H_
#include "fpdfview.h"
typedef void* FPDF_FORMHANDLE;
#ifdef PDF_ENABLE_XFA
#define DOCTYPE_PDF 0 // Normal pdf Document
#define DOCTYPE_DYNAMIC_XFA 1 // Dynamic xfa Document Type
#define DOCTYPE_STATIC_XFA 2 // Static xfa Document Type
#endif // PDF_ENABLE_XFA
// Exported Functions
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _IPDF_JsPlatform {
/**
* Version number of the interface. Currently must be 2.
**/
int version;
/* Version 1. */
/**
* Method: app_alert
* pop up a dialog to show warning or hint.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* Msg - A string containing the message to be displayed.
* Title - The title of the dialog.
* Type - The stype of button group.
* 0-OK(default);
* 1-OK,Cancel;
* 2-Yes,NO;
* 3-Yes, NO, Cancel.
* nIcon - The Icon type.
* 0-Error(default);
* 1-Warning;
* 2-Question;
* 3-Status.
* 4-Asterisk
* Return Value:
* The return value could be the folowing type:
* 1-OK;
* 2-Cancel;
* 3-NO;
* 4-Yes;
*/
int (*app_alert)(struct _IPDF_JsPlatform* pThis,
FPDF_WIDESTRING Msg,
FPDF_WIDESTRING Title,
int Type,
int Icon);
/**
* Method: app_beep
* Causes the system to play a sound.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* nType - The sound type.
* 0 - Error
* 1 - Warning
* 2 - Question
* 3 - Status
* 4 - Default (default value)
* Return Value:
* None
*/
void (*app_beep)(struct _IPDF_JsPlatform* pThis, int nType);
/**
* Method: app_response
* Displays a dialog box containing a question and an entry field for
* the user to reply to the question.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* Question - The question to be posed to the user.
* Title - The title of the dialog box.
* Default - A default value for the answer to the question. If
* not specified, no default value is presented.
* cLabel - A short string to appear in front of and on the
* same line as the edit text field.
* bPassword - If true, indicates that the user's response should
* show as asterisks (*) or bullets (?) to mask the response, which might be
* sensitive information. The default is false.
* response - A string buffer allocated by SDK, to receive the
* user's response.
* length - The length of the buffer, number of bytes.
* Currently, It's always be 2048.
* Return Value:
* Number of bytes the complete user input would actually require, not
* including trailing zeros, regardless of the value of the length
* parameter or the presence of the response buffer.
* Comments:
* No matter on what platform, the response buffer should be always
* written using UTF-16LE encoding. If a response buffer is
* present and the size of the user input exceeds the capacity of the
* buffer as specified by the length parameter, only the
* first "length" bytes of the user input are to be written to the
* buffer.
*/
int (*app_response)(struct _IPDF_JsPlatform* pThis,
FPDF_WIDESTRING Question,
FPDF_WIDESTRING Title,
FPDF_WIDESTRING Default,
FPDF_WIDESTRING cLabel,
FPDF_BOOL bPassword,
void* response,
int length);
/*
* Method: Doc_getFilePath
* Get the file path of the current document.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* filePath - The string buffer to receive the file path. Can be
* NULL.
* length - The length of the buffer, number of bytes. Can be
* 0.
* Return Value:
* Number of bytes the filePath consumes, including trailing zeros.
* Comments:
* The filePath should be always input in local encoding.
*
* The return value always indicated number of bytes required for the
* buffer, even when there is
* no buffer specified, or the buffer size is less then required. In this
* case, the buffer will not
* be modified.
*/
int (*Doc_getFilePath)(struct _IPDF_JsPlatform* pThis,
void* filePath,
int length);
/*
* Method: Doc_mail
* Mails the data buffer as an attachment to all recipients, with or
* without user interaction.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* mailData - Pointer to the data buffer to be sent.Can be NULL.
* length - The size,in bytes, of the buffer pointed by
* mailData parameter.Can be 0.
* bUI - If true, the rest of the parameters are used in a
* compose-new-message window that is displayed to the user. If false, the cTo
* parameter is required and all others are optional.
* To - A semicolon-delimited list of recipients for the
* message.
* Subject - The subject of the message. The length limit is 64
* KB.
* CC - A semicolon-delimited list of CC recipients for
* the message.
* BCC - A semicolon-delimited list of BCC recipients for
* the message.
* Msg - The content of the message. The length limit is 64
* KB.
* Return Value:
* None.
* Comments:
* If the parameter mailData is NULL or length is 0, the current
* document will be mailed as an attachment to all recipients.
*/
void (*Doc_mail)(struct _IPDF_JsPlatform* pThis,
void* mailData,
int length,
FPDF_BOOL bUI,
FPDF_WIDESTRING To,
FPDF_WIDESTRING Subject,
FPDF_WIDESTRING CC,
FPDF_WIDESTRING BCC,
FPDF_WIDESTRING Msg);
/*
* Method: Doc_print
* Prints all or a specific number of pages of the document.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* bUI - If true, will cause a UI to be presented to the
* user to obtain printing information and confirm the action.
* nStart - A 0-based index that defines the start of an
* inclusive range of pages.
* nEnd - A 0-based index that defines the end of an
* inclusive page range.
* bSilent - If true, suppresses the cancel dialog box while
* the document is printing. The default is false.
* bShrinkToFit - If true, the page is shrunk (if necessary) to
* fit within the imageable area of the printed page.
* bPrintAsImage - If true, print pages as an image.
* bReverse - If true, print from nEnd to nStart.
* bAnnotations - If true (the default), annotations are
* printed.
*/
void (*Doc_print)(struct _IPDF_JsPlatform* pThis,
FPDF_BOOL bUI,
int nStart,
int nEnd,
FPDF_BOOL bSilent,
FPDF_BOOL bShrinkToFit,
FPDF_BOOL bPrintAsImage,
FPDF_BOOL bReverse,
FPDF_BOOL bAnnotations);
/*
* Method: Doc_submitForm
* Send the form data to a specified URL.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* formData - Pointer to the data buffer to be sent.
* length - The size,in bytes, of the buffer pointed by
* formData parameter.
* URL - The URL to send to.
* Return Value:
* None.
*
*/
void (*Doc_submitForm)(struct _IPDF_JsPlatform* pThis,
void* formData,
int length,
FPDF_WIDESTRING URL);
/*
* Method: Doc_gotoPage
* Jump to a specified page.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* nPageNum - The specified page number, zero for the first
* page.
* Return Value:
* None.
*
*/
void (*Doc_gotoPage)(struct _IPDF_JsPlatform* pThis, int nPageNum);
/*
* Method: Field_browse
* Show a file selection dialog, and return the selected file path.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* filePath - Pointer to the data buffer to receive the file
* path.Can be NULL.
* length - The length of the buffer, number of bytes. Can be
* 0.
* Return Value:
* Number of bytes the filePath consumes, including trailing zeros.
* Comments:
* The filePath shoule be always input in local encoding.
*/
int (*Field_browse)(struct _IPDF_JsPlatform* pThis,
void* filePath,
int length);
/**
* pointer to FPDF_FORMFILLINFO interface.
**/
void* m_pFormfillinfo;
/* Version 2. */
void* m_isolate; /* Unused in v3, retain for compatibility. */
unsigned int m_v8EmbedderSlot; /* Unused in v3, retain for compatibility. */
/* Version 3. */
/* Version 3 moves m_Isolate and m_v8EmbedderSlot to FPDF_LIBRARY_CONFIG. */
} IPDF_JSPLATFORM;
// Flags for Cursor type
#define FXCT_ARROW 0
#define FXCT_NESW 1
#define FXCT_NWSE 2
#define FXCT_VBEAM 3
#define FXCT_HBEAM 4
#define FXCT_HAND 5
/**
* Declares of a pointer type to the callback function for the FFI_SetTimer
*method.
* Parameters:
* idEvent - Identifier of the timer.
* Return value:
* None.
**/
typedef void (*TimerCallback)(int idEvent);
/**
* Declares of a struct type to the local system time.
**/
typedef struct _FPDF_SYSTEMTIME {
unsigned short wYear; /* years since 1900 */
unsigned short wMonth; /* months since January - [0,11] */
unsigned short wDayOfWeek; /* days since Sunday - [0,6] */
unsigned short wDay; /* day of the month - [1,31] */
unsigned short wHour; /* hours since midnight - [0,23] */
unsigned short wMinute; /* minutes after the hour - [0,59] */
unsigned short wSecond; /* seconds after the minute - [0,59] */
unsigned short wMilliseconds; /* milliseconds after the second - [0,999] */
} FPDF_SYSTEMTIME;
#ifdef PDF_ENABLE_XFA
// XFA
/**
* @name Pageview event flags
*/
/*@{*/
/** @brief After a new pageview is added. */
#define FXFA_PAGEVIEWEVENT_POSTADDED 1
/** @brief After a pageview is removed. */
#define FXFA_PAGEVIEWEVENT_POSTREMOVED 3
/*@}*/
// menu
/**
* @name Macro Definitions for Right Context Menu Features Of XFA Fields
*/
/*@{*/
#define FXFA_MEMU_COPY 1
#define FXFA_MEMU_CUT 2
#define FXFA_MEMU_SELECTALL 4
#define FXFA_MEMU_UNDO 8
#define FXFA_MEMU_REDO 16
#define FXFA_MEMU_PASTE 32
/*@}*/
// file type
/**
* @name Macro Definitions for File Type.
*/
/*@{*/
#define FXFA_SAVEAS_XML 1
#define FXFA_SAVEAS_XDP 2
/*@}*/
#endif // PDF_ENABLE_XFA
typedef struct _FPDF_FORMFILLINFO {
/**
* Version number of the interface. Currently must be 1 (when PDFium is built
* without the XFA module) or must be 2 (when built with the XFA module).
**/
int version;
/* Version 1. */
/**
*Method: Release
* Give implementation a chance to release any data after the
* interface is no longer used
*Interface Version:
* 1
*Implementation Required:
* No
*Comments:
* Called by Foxit SDK during the final cleanup process.
*Parameters:
* pThis - Pointer to the interface structure itself
*Return Value:
* None
*/
void (*Release)(struct _FPDF_FORMFILLINFO* pThis);
/**
* Method: FFI_Invalidate
* Invalidate the client area within the specified rectangle.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* left - Left position of the client area in PDF page
*coordinate.
* top - Top position of the client area in PDF page
*coordinate.
* right - Right position of the client area in PDF page
*coordinate.
* bottom - Bottom position of the client area in PDF page
*coordinate.
* Return Value:
* None.
*
*comments:
* All positions are measured in PDF "user space".
* Implementation should call FPDF_RenderPageBitmap() function for
*repainting a specified page area.
*/
void (*FFI_Invalidate)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_PAGE page,
double left,
double top,
double right,
double bottom);
/**
* Method: FFI_OutputSelectedRect
* When user is taking the mouse to select texts on a form field,
* this callback function will keep
* returning the selected areas to the implementation.
*
* Interface Version:
* 1
* Implementation Required:
* No
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to the page. Returned by FPDF_LoadPage
* function.
* left - Left position of the client area in PDF page
* coordinate.
* top - Top position of the client area in PDF page
* coordinate.
* right - Right position of the client area in PDF page
* coordinate.
* bottom - Bottom position of the client area in PDF page
* coordinate.
* Return Value:
* None.
*
* comments:
* This CALLBACK function is useful for implementing special text
* selection effect. Implementation should
* first records the returned rectangles, then draw them one by one
* at the painting period, last,remove all
* the recorded rectangles when finish painting.
*/
void (*FFI_OutputSelectedRect)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_PAGE page,
double left,
double top,
double right,
double bottom);
/**
* Method: FFI_SetCursor
* Set the Cursor shape.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* nCursorType - Cursor type. see Flags for Cursor type for the
* details.
* Return value:
* None.
* */
void (*FFI_SetCursor)(struct _FPDF_FORMFILLINFO* pThis, int nCursorType);
/**
* Method: FFI_SetTimer
* This method installs a system timer. A time-out value is
* specified,
* and every time a time-out occurs, the system passes a message to
* the TimerProc callback function.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* uElapse - Specifies the time-out value, in milliseconds.
* lpTimerFunc - A pointer to the callback function-TimerCallback.
* Return value:
* The timer identifier of the new timer if the function is successful.
* An application passes this value to the FFI_KillTimer method to kill
* the timer. Nonzero if it is successful; otherwise, it is zero.
* */
int (*FFI_SetTimer)(struct _FPDF_FORMFILLINFO* pThis,
int uElapse,
TimerCallback lpTimerFunc);
/**
* Method: FFI_KillTimer
* This method kills the timer event identified by nIDEvent, set by
* an earlier call to FFI_SetTimer.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* nTimerID - The timer ID return by FFI_SetTimer function.
* Return value:
* None.
* */
void (*FFI_KillTimer)(struct _FPDF_FORMFILLINFO* pThis, int nTimerID);
/**
* Method: FFI_GetLocalTime
* This method receives the current local time on the system.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* Return value:
* None.
* */
FPDF_SYSTEMTIME (*FFI_GetLocalTime)(struct _FPDF_FORMFILLINFO* pThis);
/**
* Method: FFI_OnChange
* This method will be invoked to notify implementation when the
* value of any FormField on the document had been changed.
* Interface Version:
* 1
* Implementation Required:
* no
* Parameters:
* pThis - Pointer to the interface structure itself.
* Return value:
* None.
* */
void (*FFI_OnChange)(struct _FPDF_FORMFILLINFO* pThis);
/**
* Method: FFI_GetPage
* This method receives the page pointer associated with a specified
* page index.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* document - Handle to document. Returned by FPDF_LoadDocument
* function.
* nPageIndex - Index number of the page. 0 for the first page.
* Return value:
* Handle to the page. Returned by FPDF_LoadPage function.
* Comments:
* In some cases, the document-level JavaScript action may refer to a
* page which hadn't been loaded yet.
* To successfully run the javascript action, implementation need to load
* the page for SDK.
* */
FPDF_PAGE (*FFI_GetPage)(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, int nPageIndex);
/**
* Method: FFI_GetCurrentPage
* This method receives the current page pointer.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* document - Handle to document. Returned by FPDF_LoadDocument
* function.
* Return value:
* Handle to the page. Returned by FPDF_LoadPage function.
* */
FPDF_PAGE (*FFI_GetCurrentPage)(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document);
/**
* Method: FFI_GetRotation
* This method receives currently rotation of the page view.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to page. Returned by FPDF_LoadPage function.
* Return value:
* The page rotation. Should be 0(0 degree),1(90 degree),2(180
* degree),3(270 degree), in a clockwise direction.
* */
int (*FFI_GetRotation)(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page);
/**
* Method: FFI_ExecuteNamedAction
* This method will execute an named action.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* namedAction - A byte string which indicates the named action,
* terminated by 0.
* Return value:
* None.
* Comments:
* See the named actions description of <<PDF Reference, version 1.7>>
* for more details.
* */
void (*FFI_ExecuteNamedAction)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_BYTESTRING namedAction);
/**
* @brief This method will be called when a text field is getting or losing a
* focus.
*
* @param[in] pThis Pointer to the interface structure itself.
* @param[in] value The string value of the form field, in UTF-16LE
* format.
* @param[in] valueLen The length of the string value, number of characters
* (not bytes).
* @param[in] is_focus True if the form field is getting a focus, False for
* losing a focus.
*
* @return None.
*
* @note Currently,only support text field and combobox field.
* */
void (*FFI_SetTextFieldFocus)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_WIDESTRING value,
FPDF_DWORD valueLen,
FPDF_BOOL is_focus);
/**
* Method: FFI_DoURIAction
* This action resolves to a uniform resource identifier.
* Interface Version:
* 1
* Implementation Required:
* No
* Parameters:
* pThis - Pointer to the interface structure itself.
* bsURI - A byte string which indicates the uniform resource
* identifier, terminated by 0.
* Return value:
* None.
* Comments:
* See the URI actions description of <<PDF Reference, version 1.7>> for
* more details.
* */
void (*FFI_DoURIAction)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_BYTESTRING bsURI);
/**
* Method: FFI_DoGoToAction
* This action changes the view to a specified destination.
* Interface Version:
* 1
* Implementation Required:
* No
* Parameters:
* pThis - Pointer to the interface structure itself.
* nPageIndex - The index of the PDF page.
* zoomMode - The zoom mode for viewing page.See Macros
*"PDFZOOM_XXX" defined in "fpdfdoc.h".
* fPosArray - The float array which carries the position info.
* sizeofArray - The size of float array.
* Return value:
* None.
* Comments:
* See the Destinations description of <<PDF Reference, version 1.7>> in
*8.2.1 for more details.
**/
void (*FFI_DoGoToAction)(struct _FPDF_FORMFILLINFO* pThis,
int nPageIndex,
int zoomMode,
float* fPosArray,
int sizeofArray);
/**
* pointer to IPDF_JSPLATFORM interface
**/
IPDF_JSPLATFORM* m_pJsPlatform;
#ifdef PDF_ENABLE_XFA
/* Version 2. */
/**
* Method: FFI_DisplayCaret
* This method will show the caret at specified position.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to page. Returned by FPDF_LoadPage
*function.
* left - Left position of the client area in PDF page
*coordinate.
* top - Top position of the client area in PDF page
*coordinate.
* right - Right position of the client area in PDF page
*coordinate.
* bottom - Bottom position of the client area in PDF page
*coordinate.
* Return value:
* None.
**/
void (*FFI_DisplayCaret)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_PAGE page,
FPDF_BOOL bVisible,
double left,
double top,
double right,
double bottom);
/**
* Method: FFI_GetCurrentPageIndex
* This method will get the current page index.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* document - Handle to document. Returned by FPDF_LoadDocument
*function.
* Return value:
* The index of current page.
**/
int (*FFI_GetCurrentPageIndex)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_DOCUMENT document);
/**
* Method: FFI_SetCurrentPage
* This method will set the current page.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* document - Handle to document. Returned by FPDF_LoadDocument
*function.
* iCurPage - The index of the PDF page.
* Return value:
* None.
**/
void (*FFI_SetCurrentPage)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_DOCUMENT document,
int iCurPage);
/**
* Method: FFI_GotoURL
* This method will link to the specified URL.
* Interface Version:
* 1
* Implementation Required:
* no
* Parameters:
* pThis - Pointer to the interface structure itself.
* document - Handle to document. Returned by FPDF_LoadDocument
*function.
* wsURL - The string value of the URL, in UTF-16LE format.
* Return value:
* None.
**/
void (*FFI_GotoURL)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_DOCUMENT document,
FPDF_WIDESTRING wsURL);
/**
* Method: FFI_GetPageViewRect
* This method will get the current page view rectangle.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to page. Returned by FPDF_LoadPage
*function.
* left - The pointer to receive left position of the page
*view area in PDF page coordinate.
* top - The pointer to receive top position of the page
*view area in PDF page coordinate.
* right - The pointer to receive right position of the
*client area in PDF page coordinate.
* bottom - The pointer to receive bottom position of the
*client area in PDF page coordinate.
* Return value:
* None.
**/
void (*FFI_GetPageViewRect)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_PAGE page,
double* left,
double* top,
double* right,
double* bottom);
/**
* Method: FFI_PopupMenu
* This method will track the right context menu for XFA fields.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* page - Handle to page. Returned by FPDF_LoadPage
*function.
* hWidget - Handle to XFA fields.
* menuFlag - The menu flags. Please refer to macro definition
*of FXFA_MEMU_XXX and this can be one or a combination of these macros.
* x - X position of the client area in PDF page
*coordinate.
* y - Y position of the client area in PDF page
*coordinate.
* Return value:
* TRUE indicates success; otherwise false.
**/
FPDF_BOOL (*FFI_PopupMenu)(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_WIDGET hWidget, int menuFlag, float x, float y);
/**
* Method: FFI_OpenFile
* This method will open the specified file with the specified mode.
* Interface Version
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* fileFlag - The file flag.Please refer to macro definition of
*FXFA_SAVEAS_XXX and this can be one of these macros.
* wsURL - The string value of the file URL, in UTF-16LE
*format.
* mode - The mode for open file.
* Return value:
* The handle to FPDF_FILEHANDLER.
**/
FPDF_FILEHANDLER* (*FFI_OpenFile)(struct _FPDF_FORMFILLINFO* pThis,
int fileFlag,
FPDF_WIDESTRING wsURL,
const char* mode);
/**
* Method: FFI_EmailTo
* This method will email the specified file stream to the specified
*contacter.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* pFileHandler - Handle to the FPDF_FILEHANDLER.
* pTo - A semicolon-delimited list of recipients for the
*message,in UTF-16LE format.
* pSubject - The subject of the message,in UTF-16LE format.
* pCC - A semicolon-delimited list of CC recipients for
*the message,in UTF-16LE format.
* pBcc - A semicolon-delimited list of BCC recipients for
*the message,in UTF-16LE format.
* pMsg - Pointer to the data buffer to be sent.Can be
*NULL,in UTF-16LE format.
* Return value:
* None.
**/
void (*FFI_EmailTo)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_FILEHANDLER* fileHandler,
FPDF_WIDESTRING pTo,
FPDF_WIDESTRING pSubject,
FPDF_WIDESTRING pCC,
FPDF_WIDESTRING pBcc,
FPDF_WIDESTRING pMsg);
/**
* Method: FFI_UploadTo
* This method will get upload the specified file stream to the
*specified URL.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* pFileHandler - Handle to the FPDF_FILEHANDLER.
* fileFlag - The file flag.Please refer to macro definition of
*FXFA_SAVEAS_XXX and this can be one of these macros.
* uploadTo - Pointer to the URL path, in UTF-16LE format.
* Return value:
* None.
**/
void (*FFI_UploadTo)(struct _FPDF_FORMFILLINFO* pThis,
FPDF_FILEHANDLER* fileHandler,
int fileFlag,
FPDF_WIDESTRING uploadTo);
/**
* Method: FFI_GetPlatform
* This method will get the current platform.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* platform - Pointer to the data buffer to receive the
*platform.Can be NULL,in UTF-16LE format.
* length - The length of the buffer, number of bytes. Can be
*0.
* Return value:
* The length of the buffer, number of bytes.
**/
int (*FFI_GetPlatform)(struct _FPDF_FORMFILLINFO* pThis,
void* platform,
int length);
/**
* Method: FFI_GetLanguage
* This method will get the current language.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* language - Pointer to the data buffer to receive the current
*language.Can be NULL.
* length - The length of the buffer, number of bytes. Can be
*0.
* Return value:
* The length of the buffer, number of bytes.
**/
int (*FFI_GetLanguage)(struct _FPDF_FORMFILLINFO* pThis,
void* language,
int length);
/**
* Method: FFI_DownloadFromURL
* This method will download the specified file from the URL.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* URL - The string value of the file URL, in UTF-16LE
*format.
* Return value:
* The handle to FPDF_FILEHANDLER.
**/
FPDF_LPFILEHANDLER (*FFI_DownloadFromURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING URL);
/**
* Method: FFI_PostRequestURL
* This method will post the request to the server URL.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* wsURL - The string value of the server URL, in UTF-16LE
*format.
* wsData - The post data,in UTF-16LE format.
* wsContentType - The content type of the request data,in UTF-16LE
*format.
* wsEncode - The encode type,in UTF-16LE format.
* wsHeader - The request header,in UTF-16LE format.
* response - Pointer to the FPDF_BSTR to receive the response
*data from server,,in UTF-16LE format.
* Return value:
* TRUE indicates success, otherwise FALSE.
**/
FPDF_BOOL (*FFI_PostRequestURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsContentType, FPDF_WIDESTRING wsEncode, FPDF_WIDESTRING wsHeader, FPDF_BSTR* respone);
/**
* Method: FFI_PutRequestURL
* This method will put the request to the server URL.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself.
* wsURL - The string value of the server URL, in UTF-16LE
*format.
* wsData - The put data, in UTF-16LE format.
* wsEncode - The encode type, in UTR-16LE format.
* Return value:
* TRUE indicates success, otherwise FALSE.
**/
FPDF_BOOL (*FFI_PutRequestURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsEncode);
#endif // PDF_ENABLE_XFA
} FPDF_FORMFILLINFO;
/**
* Function: FPDFDOC_InitFormFillEnvironment
* Init form fill environment.
* Comments:
* This function should be called before any form fill operation.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* pFormFillInfo - Pointer to a FPDF_FORMFILLINFO structure.
* Return Value:
* Return handler to the form fill module. NULL means fails.
**/
DLLEXPORT FPDF_FORMHANDLE STDCALL
FPDFDOC_InitFormFillEnvironment(FPDF_DOCUMENT document,
FPDF_FORMFILLINFO* formInfo);
/**
* Function: FPDFDOC_ExitFormFillEnvironment
* Exit form fill environment.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NULL.
**/
DLLEXPORT void STDCALL FPDFDOC_ExitFormFillEnvironment(FPDF_FORMHANDLE hHandle);
/**
* Function: FORM_OnAfterLoadPage
* This method is required for implementing all the form related
*functions. Should be invoked after user
* successfully loaded a PDF page, and method
*FPDFDOC_InitFormFillEnvironment had been invoked.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NONE.
**/
DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page,
FPDF_FORMHANDLE hHandle);
/**
* Function: FORM_OnBeforeClosePage
* This method is required for implementing all the form related
*functions. Should be invoked before user
* close the PDF page.
* Parameters:
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NONE.
**/
DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page,
FPDF_FORMHANDLE hHandle);
/**
* Function: FORM_DoDocumentJSAction
* This method is required for performing Document-level JavaScript
*action. It should be invoked after the PDF document
* had been loaded.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NONE
* Comments:
* If there is Document-level JavaScript action embedded in the
*document, this method will execute the javascript action;
* otherwise, the method will do nothing.
**/
DLLEXPORT void STDCALL FORM_DoDocumentJSAction(FPDF_FORMHANDLE hHandle);
/**
* Function: FORM_DoDocumentOpenAction
* This method is required for performing open-action when the document
*is opened.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NONE
* Comments:
* This method will do nothing if there is no open-actions embedded in
*the document.
**/
DLLEXPORT void STDCALL FORM_DoDocumentOpenAction(FPDF_FORMHANDLE hHandle);
// additional actions type of document.
#define FPDFDOC_AACTION_WC \
0x10 // WC, before closing document, JavaScript action.
#define FPDFDOC_AACTION_WS \
0x11 // WS, before saving document, JavaScript action.
#define FPDFDOC_AACTION_DS 0x12 // DS, after saving document, JavaScript
// action.
#define FPDFDOC_AACTION_WP \
0x13 // WP, before printing document, JavaScript action.
#define FPDFDOC_AACTION_DP \
0x14 // DP, after printing document, JavaScript action.
/**
* Function: FORM_DoDocumentAAction
* This method is required for performing the document's
*additional-action.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* aaType - The type of the additional-actions which defined
*above.
* Return Value:
* NONE
* Comments:
* This method will do nothing if there is no document
*additional-action corresponding to the specified aaType.
**/
DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle,
int aaType);
// Additional-action types of page object
#define FPDFPAGE_AACTION_OPEN \
0 // /O -- An action to be performed when the page is opened
#define FPDFPAGE_AACTION_CLOSE \
1 // /C -- An action to be performed when the page is closed
/**
* Function: FORM_DoPageAAction
* This method is required for performing the page object's
*additional-action when opened or closed.
* Parameters:
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* aaType - The type of the page object's additional-actions
*which defined above.
* Return Value:
* NONE
* Comments:
* This method will do nothing if no additional-action corresponding to
*the specified aaType exists.
**/
DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page,
FPDF_FORMHANDLE hHandle,
int aaType);
/**
* Function: FORM_OnMouseMove
* You can call this member function when the mouse cursor moves.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* modifier - Indicates whether various virtual keys are down.
* page_x - Specifies the x-coordinate of the cursor in PDF user
*space.
* page_y - Specifies the y-coordinate of the cursor in PDF user
*space.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int modifier,
double page_x,
double page_y);
/**
* Function: FORM_OnLButtonDown
* You can call this member function when the user presses the left
*mouse button.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* modifier - Indicates whether various virtual keys are down.
* page_x - Specifies the x-coordinate of the cursor in PDF user
*space.
* page_y - Specifies the y-coordinate of the cursor in PDF user
*space.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int modifier,
double page_x,
double page_y);
/**
* Function: FORM_OnLButtonUp
* You can call this member function when the user releases the left
*mouse button.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* modifier - Indicates whether various virtual keys are down.
* page_x - Specifies the x-coordinate of the cursor in device.
* page_y - Specifies the y-coordinate of the cursor in device.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int modifier,
double page_x,
double page_y);
#ifdef PDF_ENABLE_XFA
DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int modifier,
double page_x,
double page_y);
DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int modifier,
double page_x,
double page_y);
#endif // PDF_ENABLE_XFA
/**
* Function: FORM_OnKeyDown
* You can call this member function when a nonsystem key is pressed.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* nKeyCode - Indicates whether various virtual keys are down.
* modifier - Contains the scan code, key-transition code,
*previous key state, and context code.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int nKeyCode,
int modifier);
/**
* Function: FORM_OnKeyUp
* You can call this member function when a nonsystem key is released.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* nKeyCode - The virtual-key code of the given key.
* modifier - Contains the scan code, key-transition code,
*previous key state, and context code.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int nKeyCode,
int modifier);
/**
* Function: FORM_OnChar
* You can call this member function when a keystroke translates to a
*nonsystem character.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* nChar - The character code value of the key.
* modifier - Contains the scan code, key-transition code,
*previous key state, and context code.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
int nChar,
int modifier);
/**
* Function: FORM_ForceToKillFocus.
* You can call this member function to force to kill the focus of the
*form field which got focus.
* It would kill the focus on the form field, save the value of form
*field if it's changed by user.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* TRUE indicates success; otherwise false.
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle);
// Field Types
#define FPDF_FORMFIELD_UNKNOWN 0 // Unknown.
#define FPDF_FORMFIELD_PUSHBUTTON 1 // push button type.
#define FPDF_FORMFIELD_CHECKBOX 2 // check box type.
#define FPDF_FORMFIELD_RADIOBUTTON 3 // radio button type.
#define FPDF_FORMFIELD_COMBOBOX 4 // combo box type.
#define FPDF_FORMFIELD_LISTBOX 5 // list box type.
#define FPDF_FORMFIELD_TEXTFIELD 6 // text field type.
#ifdef PDF_ENABLE_XFA
#define FPDF_FORMFIELD_XFA 7 // text field type.
#endif // PDF_ENABLE_XFA
/**
* Function: FPDFPage_HasFormFieldAtPoint
* Get the form field type by point.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
* FPDFDOC_InitFormFillEnvironment().
* page - Handle to the page. Returned by FPDF_LoadPage().
* page_x - X position in PDF "user space".
* page_y - Y position in PDF "user space".
* Return Value:
* Return the type of the form field; -1 indicates no field.
* See field types above.
**/
DLLEXPORT int STDCALL FPDFPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
double page_x,
double page_y);
/**
* Function: FPDPage_HasFormFieldAtPoint
* DEPRECATED. Please use FPDFPage_HasFormFieldAtPoint.
**/
DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
double page_x,
double page_y);
/**
* Function: FPDFPage_FormFieldZOrderAtPoint
* Get the form field z-order by point.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
* FPDFDOC_InitFormFillEnvironment().
* page - Handle to the page. Returned by FPDF_LoadPage().
* page_x - X position in PDF "user space".
* page_y - Y position in PDF "user space".
* Return Value:
* Return the z-order of the form field; -1 indicates no field.
* Higher numbers are closer to the front.
**/
DLLEXPORT int STDCALL FPDFPage_FormFieldZOrderAtPoint(FPDF_FORMHANDLE hHandle,
FPDF_PAGE page,
double page_x,
double page_y);
/**
* Function: FPDF_SetFormFieldHighlightColor
* Set the highlight color of specified or all the form fields in the
*document.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* doc - Handle to the document. Returned by
*FPDF_LoadDocument function.
* fieldType - A 32-bit integer indicating the type of a form
*field(defined above).
* color - The highlight color of the form field.Constructed by
*0xxxrrggbb.
* Return Value:
* NONE.
* Comments:
* When the parameter fieldType is set to zero, the highlight color
*will be applied to all the form fields in the
* document.
* Please refresh the client window to show the highlight immediately
*if necessary.
**/
DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle,
int fieldType,
unsigned long color);
/**
* Function: FPDF_SetFormFieldHighlightAlpha
* Set the transparency of the form field highlight color in the
*document.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* doc - Handle to the document. Returned by
*FPDF_LoadDocument function.
* alpha - The transparency of the form field highlight color.
*between 0-255.
* Return Value:
* NONE.
**/
DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightAlpha(FPDF_FORMHANDLE hHandle,
unsigned char alpha);
/**
* Function: FPDF_RemoveFormFieldHighlight
* Remove the form field highlight color in the document.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* Return Value:
* NONE.
* Comments:
* Please refresh the client window to remove the highlight immediately
*if necessary.
**/
DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle);
/**
* Function: FPDF_FFLDraw
* Render FormFeilds on a page to a device independent bitmap.
* Parameters:
* hHandle - Handle to the form fill module. Returned by
*FPDFDOC_InitFormFillEnvironment.
* bitmap - Handle to the device independent bitmap (as the
*output buffer).
* Bitmap handle can be created by FPDFBitmap_Create
*function.
* page - Handle to the page. Returned by FPDF_LoadPage
*function.
* start_x - Left pixel position of the display area in the
*device coordinate.
* start_y - Top pixel position of the display area in the device
*coordinate.
* size_x - Horizontal size (in pixels) for displaying the page.
* size_y - Vertical size (in pixels) for displaying the page.
* rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees
*clockwise),
* 2 (rotated 180 degrees), 3 (rotated 90 degrees
*counter-clockwise).
* flags - 0 for normal display, or combination of flags
*defined above.
* Return Value:
* None.
* Comments:
* This method is designed to only render annotations and FormFields on
*the page.
* Without FPDF_ANNOT specified for flags, Rendering functions such as
*FPDF_RenderPageBitmap or FPDF_RenderPageBitmap_Start will only render page
*contents(without annotations) to a bitmap.
* In order to implement the FormFill functions,Implementation should
*call this method after rendering functions finish rendering the page contents.
**/
DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,
FPDF_BITMAP bitmap,
FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags);
#ifdef PDF_ENABLE_XFA
/**
* Function: FPDF_HasXFAField
* This method is designed to check whether a pdf document
*has XFA fields.
* Parameters:
* document - Handle to document.
*Returned by FPDF_LoadDocument function.
* docType - Document type defined as
*DOCTYPE_xxx.
* Return Value:
* TRUE indicates that the input document has XFA fields,
*otherwise FALSE.
**/
DLLEXPORT FPDF_BOOL STDCALL FPDF_HasXFAField(FPDF_DOCUMENT document,
int* docType);
/**
* Function: FPDF_LoadXFA
* If the document consists of XFA fields, there should call this
*method to load XFA fields.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* Return Value:
* TRUE indicates success,otherwise FALSE.
**/
DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document);
/**
* Function: FPDF_Widget_Undo
* This method will implement the undo feature for the specified xfa
*field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget);
/**
* Function: FPDF_Widget_Redo
* This method will implement the redo feature for the specified xfa
*field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget);
/**
* Function: FPDF_Widget_SelectAll
* This method will implement the select all feature for the specified
*xfa field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget);
/**
* Function: FPDF_Widget_Copy
* This method will implement the copy feature for the specified xfa
*field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* wsText - Pointer to data buffer to receive the copied
*data, in UTF-16LE format.
* size - The data buffer size.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget,
FPDF_WIDESTRING wsText,
FPDF_DWORD* size);
/**
* Function: FPDF_Widget_Cut
* This method will implement the cut feature for the specified xfa
*field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* wsText - Pointer to data buffer to receive the cut
*data,in UTF-16LE format.
* size - The data buffer size,not the byte number.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget,
FPDF_WIDESTRING wsText,
FPDF_DWORD* size);
/**
* Function: FPDF_Widget_Paste
* This method will implement the paste feature for the specified xfa
*field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* wsText - The paste text buffer, in UTF-16LE format.
* size - The data buffer size,not the byte number.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget,
FPDF_WIDESTRING wsText,
FPDF_DWORD size);
/**
* Function: FPDF_Widget_ReplaceSpellCheckWord
* This method will implement the spell check feature for the specified
*xfa field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* x - The x value of the specified point.
* y - The y value of the specified point.
* bsText - The text buffer needed to be speck check, in
*UTF-16LE format.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL
FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget,
float x,
float y,
FPDF_BYTESTRING bsText);
/**
* Function: FPDF_Widget_GetSpellCheckWords
* This method will implement the spell check feature for the specified
*xfa field.
* Parameters:
* document - Handle to document. Returned by
*FPDF_LoadDocument function.
* hWidget - Handle to the xfa field.
* x - The x value of the specified point.
* y - The y value of the specified point.
* stringHandle - Pointer to FPDF_STRINGHANDLE to receive the
*speck check text buffer, in UTF-16LE format.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL
FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document,
FPDF_WIDGET hWidget,
float x,
float y,
FPDF_STRINGHANDLE* stringHandle);
/**
* Function: FPDF_StringHandleCounts
* This method will get the count of the text buffer.
* Parameters:
* stringHandle - Pointer to FPDF_STRINGHANDLE.
* Return Value:
* None.
**/
DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE stringHandle);
/**
* Function: FPDF_StringHandleGetStringByIndex
* This method will get the specified index of the text buffer.
* Parameters:
* stringHandle - Pointer to FPDF_STRINGHANDLE.
* index - The specified index of text buffer.
* bsText - Pointer to data buffer to receive the text
*buffer, in UTF-16LE format.
* size - The byte size of data buffer.
* Return Value:
* TRUE indicates success, otherwise FALSE.
**/
DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE stringHandle,
int index,
FPDF_BYTESTRING bsText,
FPDF_DWORD* size);
/**
* Function: FPDF_StringHandleRelease
* This method will release the FPDF_STRINGHANDLE.
* Parameters:
* stringHandle - Pointer to FPDF_STRINGHANDLE.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle);
/**
* Function: FPDF_StringHandleAddString
* This method will add the specified text buffer.
* Parameters:
* stringHandle - Pointer to FPDF_STRINGHANDLE.
* bsText - Pointer to data buffer of the text buffer, in
*UTF-16LE format.
* size - The byte size of data buffer.
* Return Value:
* TRUE indicates success, otherwise FALSE.
**/
DLLEXPORT FPDF_BOOL STDCALL
FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle,
FPDF_BYTESTRING bsText,
FPDF_DWORD size);
#endif // PDF_ENABLE_XFA
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_FORMFILL_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_FWLEVENT_H_
#define PUBLIC_FPDF_FWLEVENT_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef int FPDF_INT32;
typedef unsigned int FPDF_UINT32;
typedef float FPDF_FLOAT;
// event type
typedef enum {
FWL_EVENTTYPE_Mouse = 0,
FWL_EVENTTYPE_MouseWheel,
FWL_EVENTTYPE_Key,
} FWL_EVENTTYPE;
// key flag
typedef enum {
FWL_EVENTFLAG_ShiftKey = 1 << 0,
FWL_EVENTFLAG_ControlKey = 1 << 1,
FWL_EVENTFLAG_AltKey = 1 << 2,
FWL_EVENTFLAG_MetaKey = 1 << 3,
FWL_EVENTFLAG_KeyPad = 1 << 4,
FWL_EVENTFLAG_AutoRepeat = 1 << 5,
FWL_EVENTFLAG_LeftButtonDown = 1 << 6,
FWL_EVENTFLAG_MiddleButtonDown = 1 << 7,
FWL_EVENTFLAG_RightButtonDown = 1 << 8,
} FWL_EVENTFLAG;
// Mouse message command
typedef enum {
FWL_EVENTMOUSECMD_LButtonDown = 1,
FWL_EVENTMOUSECMD_LButtonUp,
FWL_EVENTMOUSECMD_LButtonDblClk,
FWL_EVENTMOUSECMD_RButtonDown,
FWL_EVENTMOUSECMD_RButtonUp,
FWL_EVENTMOUSECMD_RButtonDblClk,
FWL_EVENTMOUSECMD_MButtonDown,
FWL_EVENTMOUSECMD_MButtonUp,
FWL_EVENTMOUSECMD_MButtonDblClk,
FWL_EVENTMOUSECMD_MouseMove,
FWL_EVENTMOUSECMD_MouseEnter,
FWL_EVENTMOUSECMD_MouseHover,
FWL_EVENTMOUSECMD_MouseLeave,
} FWL_EVENT_MOUSECMD;
// mouse event
struct FWL_EVENT_MOUSE {
FPDF_UINT32 command;
FPDF_DWORD flag;
FPDF_FLOAT x;
FPDF_FLOAT y;
};
// mouse wheel
struct FWL_EVENT_MOUSEWHEEL {
FPDF_DWORD flag;
FPDF_FLOAT x;
FPDF_FLOAT y;
FPDF_FLOAT deltaX;
FPDF_FLOAT deltaY;
};
// virtual keycode
typedef enum {
FWL_VKEY_Back = 0x08,
FWL_VKEY_Tab = 0x09,
FWL_VKEY_Clear = 0x0C,
FWL_VKEY_Return = 0x0D,
FWL_VKEY_Shift = 0x10,
FWL_VKEY_Control = 0x11,
FWL_VKEY_Menu = 0x12,
FWL_VKEY_Pause = 0x13,
FWL_VKEY_Capital = 0x14,
FWL_VKEY_Kana = 0x15,
FWL_VKEY_Hangul = 0x15,
FWL_VKEY_Junja = 0x17,
FWL_VKEY_Final = 0x18,
FWL_VKEY_Hanja = 0x19,
FWL_VKEY_Kanji = 0x19,
FWL_VKEY_Escape = 0x1B,
FWL_VKEY_Convert = 0x1C,
FWL_VKEY_NonConvert = 0x1D,
FWL_VKEY_Accept = 0x1E,
FWL_VKEY_ModeChange = 0x1F,
FWL_VKEY_Space = 0x20,
FWL_VKEY_Prior = 0x21,
FWL_VKEY_Next = 0x22,
FWL_VKEY_End = 0x23,
FWL_VKEY_Home = 0x24,
FWL_VKEY_Left = 0x25,
FWL_VKEY_Up = 0x26,
FWL_VKEY_Right = 0x27,
FWL_VKEY_Down = 0x28,
FWL_VKEY_Select = 0x29,
FWL_VKEY_Print = 0x2A,
FWL_VKEY_Execute = 0x2B,
FWL_VKEY_Snapshot = 0x2C,
FWL_VKEY_Insert = 0x2D,
FWL_VKEY_Delete = 0x2E,
FWL_VKEY_Help = 0x2F,
FWL_VKEY_0 = 0x30,
FWL_VKEY_1 = 0x31,
FWL_VKEY_2 = 0x32,
FWL_VKEY_3 = 0x33,
FWL_VKEY_4 = 0x34,
FWL_VKEY_5 = 0x35,
FWL_VKEY_6 = 0x36,
FWL_VKEY_7 = 0x37,
FWL_VKEY_8 = 0x38,
FWL_VKEY_9 = 0x39,
FWL_VKEY_A = 0x41,
FWL_VKEY_B = 0x42,
FWL_VKEY_C = 0x43,
FWL_VKEY_D = 0x44,
FWL_VKEY_E = 0x45,
FWL_VKEY_F = 0x46,
FWL_VKEY_G = 0x47,
FWL_VKEY_H = 0x48,
FWL_VKEY_I = 0x49,
FWL_VKEY_J = 0x4A,
FWL_VKEY_K = 0x4B,
FWL_VKEY_L = 0x4C,
FWL_VKEY_M = 0x4D,
FWL_VKEY_N = 0x4E,
FWL_VKEY_O = 0x4F,
FWL_VKEY_P = 0x50,
FWL_VKEY_Q = 0x51,
FWL_VKEY_R = 0x52,
FWL_VKEY_S = 0x53,
FWL_VKEY_T = 0x54,
FWL_VKEY_U = 0x55,
FWL_VKEY_V = 0x56,
FWL_VKEY_W = 0x57,
FWL_VKEY_X = 0x58,
FWL_VKEY_Y = 0x59,
FWL_VKEY_Z = 0x5A,
FWL_VKEY_LWin = 0x5B,
FWL_VKEY_Command = 0x5B,
FWL_VKEY_RWin = 0x5C,
FWL_VKEY_Apps = 0x5D,
FWL_VKEY_Sleep = 0x5F,
FWL_VKEY_NumPad0 = 0x60,
FWL_VKEY_NumPad1 = 0x61,
FWL_VKEY_NumPad2 = 0x62,
FWL_VKEY_NumPad3 = 0x63,
FWL_VKEY_NumPad4 = 0x64,
FWL_VKEY_NumPad5 = 0x65,
FWL_VKEY_NumPad6 = 0x66,
FWL_VKEY_NumPad7 = 0x67,
FWL_VKEY_NumPad8 = 0x68,
FWL_VKEY_NumPad9 = 0x69,
FWL_VKEY_Multiply = 0x6A,
FWL_VKEY_Add = 0x6B,
FWL_VKEY_Separator = 0x6C,
FWL_VKEY_Subtract = 0x6D,
FWL_VKEY_Decimal = 0x6E,
FWL_VKEY_Divide = 0x6F,
FWL_VKEY_F1 = 0x70,
FWL_VKEY_F2 = 0x71,
FWL_VKEY_F3 = 0x72,
FWL_VKEY_F4 = 0x73,
FWL_VKEY_F5 = 0x74,
FWL_VKEY_F6 = 0x75,
FWL_VKEY_F7 = 0x76,
FWL_VKEY_F8 = 0x77,
FWL_VKEY_F9 = 0x78,
FWL_VKEY_F10 = 0x79,
FWL_VKEY_F11 = 0x7A,
FWL_VKEY_F12 = 0x7B,
FWL_VKEY_F13 = 0x7C,
FWL_VKEY_F14 = 0x7D,
FWL_VKEY_F15 = 0x7E,
FWL_VKEY_F16 = 0x7F,
FWL_VKEY_F17 = 0x80,
FWL_VKEY_F18 = 0x81,
FWL_VKEY_F19 = 0x82,
FWL_VKEY_F20 = 0x83,
FWL_VKEY_F21 = 0x84,
FWL_VKEY_F22 = 0x85,
FWL_VKEY_F23 = 0x86,
FWL_VKEY_F24 = 0x87,
FWL_VKEY_NunLock = 0x90,
FWL_VKEY_Scroll = 0x91,
FWL_VKEY_LShift = 0xA0,
FWL_VKEY_RShift = 0xA1,
FWL_VKEY_LControl = 0xA2,
FWL_VKEY_RControl = 0xA3,
FWL_VKEY_LMenu = 0xA4,
FWL_VKEY_RMenu = 0xA5,
FWL_VKEY_BROWSER_Back = 0xA6,
FWL_VKEY_BROWSER_Forward = 0xA7,
FWL_VKEY_BROWSER_Refresh = 0xA8,
FWL_VKEY_BROWSER_Stop = 0xA9,
FWL_VKEY_BROWSER_Search = 0xAA,
FWL_VKEY_BROWSER_Favorites = 0xAB,
FWL_VKEY_BROWSER_Home = 0xAC,
FWL_VKEY_VOLUME_Mute = 0xAD,
FWL_VKEY_VOLUME_Down = 0xAE,
FWL_VKEY_VOLUME_Up = 0xAF,
FWL_VKEY_MEDIA_NEXT_Track = 0xB0,
FWL_VKEY_MEDIA_PREV_Track = 0xB1,
FWL_VKEY_MEDIA_Stop = 0xB2,
FWL_VKEY_MEDIA_PLAY_Pause = 0xB3,
FWL_VKEY_MEDIA_LAUNCH_Mail = 0xB4,
FWL_VKEY_MEDIA_LAUNCH_MEDIA_Select = 0xB5,
FWL_VKEY_MEDIA_LAUNCH_APP1 = 0xB6,
FWL_VKEY_MEDIA_LAUNCH_APP2 = 0xB7,
FWL_VKEY_OEM_1 = 0xBA,
FWL_VKEY_OEM_Plus = 0xBB,
FWL_VKEY_OEM_Comma = 0xBC,
FWL_VKEY_OEM_Minus = 0xBD,
FWL_VKEY_OEM_Period = 0xBE,
FWL_VKEY_OEM_2 = 0xBF,
FWL_VKEY_OEM_3 = 0xC0,
FWL_VKEY_OEM_4 = 0xDB,
FWL_VKEY_OEM_5 = 0xDC,
FWL_VKEY_OEM_6 = 0xDD,
FWL_VKEY_OEM_7 = 0xDE,
FWL_VKEY_OEM_8 = 0xDF,
FWL_VKEY_OEM_102 = 0xE2,
FWL_VKEY_ProcessKey = 0xE5,
FWL_VKEY_Packet = 0xE7,
FWL_VKEY_Attn = 0xF6,
FWL_VKEY_Crsel = 0xF7,
FWL_VKEY_Exsel = 0xF8,
FWL_VKEY_Ereof = 0xF9,
FWL_VKEY_Play = 0xFA,
FWL_VKEY_Zoom = 0xFB,
FWL_VKEY_NoName = 0xFC,
FWL_VKEY_PA1 = 0xFD,
FWL_VKEY_OEM_Clear = 0xFE,
FWL_VKEY_Unknown = 0,
} FWL_VKEYCODE;
// key event command
typedef enum {
FWL_EVENTKEYCMD_KeyDown = 1,
FWL_EVENTKEYCMD_KeyUp,
FWL_EVENTKEYCMD_Char,
} FWL_EVENTKEYCMD;
// key event
struct FWL_EVENT_KEY {
FPDF_UINT32 command;
FPDF_DWORD flag;
union {
// Virtual key code.
FPDF_UINT32 vkcode;
// Character code.
FPDF_DWORD charcode;
} code;
};
// event type
struct FWL_EVENT {
// structure size.
FPDF_UINT32 size;
// FWL_EVENTTYPE.
FPDF_UINT32 type;
union {
struct FWL_EVENT_MOUSE mouse;
struct FWL_EVENT_MOUSEWHEEL wheel;
struct FWL_EVENT_KEY key;
} s;
};
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_FWLEVENT_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_PPO_H_
#define PUBLIC_FPDF_PPO_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDF_ImportPages
// Import some pages to a PDF document.
// Parameters:
// dest_doc - The destination document which add the pages.
// src_doc - A document to be imported.
// pagerange - A page range string, Such as "1,3,5-7".
// If this parameter is NULL, it would import all pages
// in src_doc.
// index - The page index wanted to insert from.
// Return value:
// TRUE for succeed, FALSE for Failed.
DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
FPDF_DOCUMENT src_doc,
FPDF_BYTESTRING pagerange,
int index);
// Function: FPDF_CopyViewerPreferences
// Copy the viewer preferences from one PDF document to another.#endif
// Parameters:
// dest_doc - Handle to document to write the viewer preferences
// to.
// src_doc - Handle to document with the viewer preferences.
// Return value:
// TRUE for success, FALSE for failure.
DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
FPDF_DOCUMENT src_doc);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_PPO_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_PROGRESSIVE_H_
#define PUBLIC_FPDF_PROGRESSIVE_H_
#include "fpdfview.h"
// Flags for progressive process status.
#define FPDF_RENDER_READER 0
#define FPDF_RENDER_TOBECOUNTINUED 1
#define FPDF_RENDER_DONE 2
#define FPDF_RENDER_FAILED 3
#ifdef __cplusplus
extern "C" {
#endif
// IFPDF_RENDERINFO interface.
typedef struct _IFSDK_PAUSE {
/**
* Version number of the interface. Currently must be 1.
**/
int version;
/*
* Method: NeedToPauseNow
* Check if we need to pause a progressive process now.
* Interface Version:
* 1
* Implementation Required:
* yes
* Parameters:
* pThis - Pointer to the interface structure itself
* Return Value:
* Non-zero for pause now, 0 for continue.
*
*/
FPDF_BOOL (*NeedToPauseNow)(struct _IFSDK_PAUSE* pThis);
// A user defined data pointer, used by user's application. Can be NULL.
void* user;
} IFSDK_PAUSE;
// Function: FPDF_RenderPageBitmap_Start
// Start to render page contents to a device independent bitmap
// progressively.
// Parameters:
// bitmap - Handle to the device independent bitmap (as the
// output buffer).
// Bitmap handle can be created by FPDFBitmap_Create
// function.
// page - Handle to the page. Returned by FPDF_LoadPage
// function.
// start_x - Left pixel position of the display area in the
// bitmap coordinate.
// start_y - Top pixel position of the display area in the bitmap
// coordinate.
// size_x - Horizontal size (in pixels) for displaying the page.
// size_y - Vertical size (in pixels) for displaying the page.
// rotate - Page orientation: 0 (normal), 1 (rotated 90 degrees
// clockwise),
// 2 (rotated 180 degrees), 3 (rotated 90 degrees
// counter-clockwise).
// flags - 0 for normal display, or combination of flags
// defined above.
// pause - The IFSDK_PAUSE interface.A callback mechanism
// allowing the page rendering process
// Return value:
// Rendering Status. See flags for progressive process status for the
// details.
//
DLLEXPORT int STDCALL FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,
FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags,
IFSDK_PAUSE* pause);
// Function: FPDF_RenderPage_Continue
// Continue rendering a PDF page.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage
// function.
// pause - The IFSDK_PAUSE interface.A callback mechanism
// allowing the page rendering process
// to be paused before it's finished. This can be NULL
// if you don't want to pause.
// Return value:
// The rendering status. See flags for progressive process status for
// the details.
DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,
IFSDK_PAUSE* pause);
// Function: FPDF_RenderPage_Close
// Release the resource allocate during page rendering. Need to be
// called after finishing rendering or
// cancel the rendering.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage
// function.
// Return value:
// NULL
DLLEXPORT void STDCALL FPDF_RenderPage_Close(FPDF_PAGE page);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_PROGRESSIVE_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_SAVE_H_
#define PUBLIC_FPDF_SAVE_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
// Structure for custom file write
typedef struct FPDF_FILEWRITE_ {
//
// Version number of the interface. Currently must be 1.
//
int version;
//
// Method: WriteBlock
// Output a block of data in your custom way.
// Interface Version:
// 1
// Implementation Required:
// Yes
// Comments:
// Called by function FPDF_SaveDocument
// Parameters:
// pThis - Pointer to the structure itself
// pData - Pointer to a buffer to output
// size - The size of the buffer.
// Return value:
// Should be non-zero if successful, zero for error.
//
int (*WriteBlock)(struct FPDF_FILEWRITE_* pThis,
const void* pData,
unsigned long size);
} FPDF_FILEWRITE;
/** @brief Incremental. */
#define FPDF_INCREMENTAL 1
/** @brief No Incremental. */
#define FPDF_NO_INCREMENTAL 2
/** @brief Remove security. */
#define FPDF_REMOVE_SECURITY 3
// Function: FPDF_SaveAsCopy
// Saves the copy of specified document in custom way.
// Parameters:
// document - Handle to document. Returned by
// FPDF_LoadDocument and FPDF_CreateNewDocument.
// pFileWrite - A pointer to a custom file write structure.
// flags - The creating flags.
// Return value:
// TRUE for succeed, FALSE for failed.
//
DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
FPDF_FILEWRITE* pFileWrite,
FPDF_DWORD flags);
// Function: FPDF_SaveWithVersion
// Same as function ::FPDF_SaveAsCopy, except the file version of the
// saved document could be specified by user.
// Parameters:
// document - Handle to document.
// pFileWrite - A pointer to a custom file write structure.
// flags - The creating flags.
// fileVersion - The PDF file version. File version: 14 for 1.4,
// 15 for 1.5, ...
// Return value:
// TRUE if succeed, FALSE if failed.
//
DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
FPDF_FILEWRITE* pFileWrite,
FPDF_DWORD flags,
int fileVersion);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_SAVE_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_SEARCHEX_H_
#define PUBLIC_FPDF_SEARCHEX_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDFText_GetCharIndexFromTextIndex
// Get the actually char index in text_page's internal char list.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// nTextIndex - The index of the text in the string get from
// FPDFText_GetText.
// Return value:
// The index of the character in internal charlist. -1 for error.
DLLEXPORT int STDCALL
FPDFText_GetCharIndexFromTextIndex(FPDF_TEXTPAGE text_page, int nTextIndex);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_SEARCHEX_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_SYSFONTINFO_H_
#define PUBLIC_FPDF_SYSFONTINFO_H_
#include "fpdfview.h"
/* Character sets for the font */
#define FXFONT_ANSI_CHARSET 0
#define FXFONT_DEFAULT_CHARSET 1
#define FXFONT_SYMBOL_CHARSET 2
#define FXFONT_SHIFTJIS_CHARSET 128
#define FXFONT_HANGEUL_CHARSET 129
#define FXFONT_GB2312_CHARSET 134
#define FXFONT_CHINESEBIG5_CHARSET 136
/* Font pitch and family flags */
#define FXFONT_FF_FIXEDPITCH 1
#define FXFONT_FF_ROMAN (1 << 4)
#define FXFONT_FF_SCRIPT (4 << 4)
/* Typical weight values */
#define FXFONT_FW_NORMAL 400
#define FXFONT_FW_BOLD 700
// Exported Functions
#ifdef __cplusplus
extern "C" {
#endif
/**
* Interface: FPDF_SYSFONTINFO
* Interface for getting system font information and font mapping
*/
typedef struct _FPDF_SYSFONTINFO {
/**
* Version number of the interface. Currently must be 1.
**/
int version;
/**
* Method: Release
* Give implementation a chance to release any data after the
* interface is no longer used
* Interface Version:
* 1
* Implementation Required:
* No
* Comments:
* Called by Foxit SDK during the final cleanup process.
* Parameters:
* pThis - Pointer to the interface structure itself
* Return Value:
* None
*/
void (*Release)(struct _FPDF_SYSFONTINFO* pThis);
/**
* Method: EnumFonts
* Enumerate all fonts installed on the system
* Interface Version:
* 1
* Implementation Required:
* No
* Comments:
* Implementation should call FPDF_AddIntalledFont() function for
* each font found.
* Only TrueType/OpenType and Type1 fonts are accepted by Foxit SDK.
* Parameters:
* pThis - Pointer to the interface structure itself
* pMapper - An opaque pointer to internal font mapper, used
* when calling FPDF_AddInstalledFont
* Return Value:
* None
*/
void (*EnumFonts)(struct _FPDF_SYSFONTINFO* pThis, void* pMapper);
/**
* Method: MapFont
* Use the system font mapper to get a font handle from requested
*parameters
* Interface Version:
* 1
* Implementation Required:
* Yes only if GetFont method is not implemented.
* Comments:
* If the system supports native font mapper (like Windows),
*implementation can implement this method to get a font handle.
* Otherwise, Foxit SDK will do the mapping and then call GetFont
*method.
* Only TrueType/OpenType and Type1 fonts are accepted by Foxit SDK.
* Parameters:
* pThis - Pointer to the interface structure itself
* weight - Weight of the requested font. 400 is normal and
*700 is bold.
* bItalic - Italic option of the requested font, TRUE or
*FALSE.
* charset - Character set identifier for the requested font.
*See above defined constants.
* pitch_family - A combination of flags. See above defined
*constants.
* face - Typeface name. Currently use system local encoding
*only.
* bExact - Pointer to a boolean value receiving the indicator
*whether mapper found the exact match.
* If mapper is not sure whether it's exact match,
*ignore this paramter.
* Return Value:
* An opaque pointer for font handle, or NULL if system mapping is
*not supported.
**/
void* (*MapFont)(struct _FPDF_SYSFONTINFO* pThis,
int weight,
FPDF_BOOL bItalic,
int charset,
int pitch_family,
const char* face,
FPDF_BOOL* bExact);
/**
* Method: GetFont
* Get a handle to a particular font by its internal ID
* Interface Version:
* 1
* Implementation Required:
* Yes only if MapFont method is not implemented.
* Comments:
* If the system mapping not supported, Foxit SDK will do the font
*mapping and use this method to get a font handle.
* Parameters:
* pThis - Pointer to the interface structure itself
* face - Typeface name. Currently use system local encoding
*only.
* Return Value:
* An opaque pointer for font handle.
**/
void* (*GetFont)(struct _FPDF_SYSFONTINFO* pThis, const char* face);
/**
* Method: GetFontData
* Get font data from a font
* Interface Version:
* 1
* Implementation Required:
* Yes
* Comments:
* Can read either full font file, or a particular TrueType/OpenType
*table
* Parameters:
* pThis - Pointer to the interface structure itself
* hFont - Font handle returned by MapFont or GetFont method
* table - TrueType/OpenType table identifier (refer to
*TrueType specification).
* 0 for the whole font file.
* buffer - The buffer receiving the font data. Can be NULL if
*not provided
* buf_size - Buffer size, can be zero if not provided
* Return Value:
* Number of bytes needed, if buffer not provided or not large
*enough,
* or number of bytes written into buffer otherwise.
**/
unsigned long (*GetFontData)(struct _FPDF_SYSFONTINFO* pThis,
void* hFont,
unsigned int table,
unsigned char* buffer,
unsigned long buf_size);
/**
* Method: GetFaceName
* Get face name from a font handle
* Interface Version:
* 1
* Implementation Required:
* No
* Parameters:
* pThis - Pointer to the interface structure itself
* hFont - Font handle returned by MapFont or GetFont method
* buffer - The buffer receiving the face name. Can be NULL if
*not provided
* buf_size - Buffer size, can be zero if not provided
* Return Value:
* Number of bytes needed, if buffer not provided or not large
*enough,
* or number of bytes written into buffer otherwise.
**/
unsigned long (*GetFaceName)(struct _FPDF_SYSFONTINFO* pThis,
void* hFont,
char* buffer,
unsigned long buf_size);
/**
* Method: GetFontCharset
* Get character set information for a font handle
* Interface Version:
* 1
* Implementation Required:
* No
* Parameters:
* pThis - Pointer to the interface structure itself
* hFont - Font handle returned by MapFont or GetFont method
* Return Value:
* Character set identifier. See defined constants above.
**/
int (*GetFontCharset)(struct _FPDF_SYSFONTINFO* pThis, void* hFont);
/**
* Method: DeleteFont
* Delete a font handle
* Interface Version:
* 1
* Implementation Required:
* Yes
* Parameters:
* pThis - Pointer to the interface structure itself
* hFont - Font handle returned by MapFont or GetFont method
* Return Value:
* None
**/
void (*DeleteFont)(struct _FPDF_SYSFONTINFO* pThis, void* hFont);
} FPDF_SYSFONTINFO;
/**
* Struct: FPDF_CharsetFontMap
* Provides the name of a font to use for a given charset value.
**/
typedef struct FPDF_CharsetFontMap_ {
int charset; // Character Set Enum value, see FXFONT_*_CHARSET above.
const char* fontname; // Name of default font to use with that charset.
} FPDF_CharsetFontMap;
/**
* Function: FPDF_GetDefaultTTFMap
* Returns a pointer to the default character set to TT Font name map. The
* map is an array of FPDF_CharsetFontMap structs, with its end indicated
* by a { -1, NULL } entry.
* Parameters:
* None.
* Return Value:
* Pointer to the Charset Font Map.
**/
DLLEXPORT const FPDF_CharsetFontMap* STDCALL FPDF_GetDefaultTTFMap();
/**
* Function: FPDF_AddInstalledFont
* Add a system font to the list in Foxit SDK.
* Comments:
* This function is only called during the system font list building
*process.
* Parameters:
* mapper - Opaque pointer to Foxit font mapper
* face - The font face name
* charset - Font character set. See above defined constants.
* Return Value:
* None.
**/
DLLEXPORT void STDCALL FPDF_AddInstalledFont(void* mapper,
const char* face,
int charset);
/**
* Function: FPDF_SetSystemFontInfo
* Set the system font info interface into Foxit SDK
* Comments:
* Platform support implementation should implement required methods of
*FFDF_SYSFONTINFO interface,
* then call this function during SDK initialization process.
* Parameters:
* pFontInfo - Pointer to a FPDF_SYSFONTINFO structure
* Return Value:
* None
**/
DLLEXPORT void STDCALL FPDF_SetSystemFontInfo(FPDF_SYSFONTINFO* pFontInfo);
/**
* Function: FPDF_GetDefaultSystemFontInfo
* Get default system font info interface for current platform
* Comments:
* For some platforms Foxit SDK implement a default version of system
*font info interface.
* The default implementation can be used in FPDF_SetSystemFontInfo
*function.
* Parameters:
* None
* Return Value:
* Pointer to a FPDF_SYSFONTINFO structure describing the default
*interface.
* Or NULL if the platform doesn't have a default interface.
* Application should call FPDF_FreeMemory to free the returned
*pointer.
**/
DLLEXPORT FPDF_SYSFONTINFO* STDCALL FPDF_GetDefaultSystemFontInfo();
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_SYSFONTINFO_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_TEXT_H_
#define PUBLIC_FPDF_TEXT_H_
#include "fpdfview.h"
// Exported Functions
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDFText_LoadPage
// Prepare information about all characters in a page.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage function
// (in FPDFVIEW module).
// Return value:
// A handle to the text page information structure.
// NULL if something goes wrong.
// Comments:
// Application must call FPDFText_ClosePage to release the text page
// information.
//
DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page);
// Function: FPDFText_ClosePage
// Release all resources allocated for a text page information
// structure.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// Return Value:
// None.
//
DLLEXPORT void STDCALL FPDFText_ClosePage(FPDF_TEXTPAGE text_page);
// Function: FPDFText_CountChars
// Get number of characters in a page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// Return value:
// Number of characters in the page. Return -1 for error.
// Generated characters, like additional space characters, new line
// characters, are also counted.
// Comments:
// Characters in a page form a "stream", inside the stream, each
// character has an index.
// We will use the index parameters in many of FPDFTEXT functions. The
// first character in the page
// has an index value of zero.
//
DLLEXPORT int STDCALL FPDFText_CountChars(FPDF_TEXTPAGE text_page);
// Function: FPDFText_GetUnicode
// Get Unicode of a character in a page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// index - Zero-based index of the character.
// Return value:
// The Unicode of the particular character.
// If a character is not encoded in Unicode and Foxit engine can't
// convert to Unicode,
// the return value will be zero.
//
DLLEXPORT unsigned int STDCALL FPDFText_GetUnicode(FPDF_TEXTPAGE text_page,
int index);
// Function: FPDFText_GetFontSize
// Get the font size of a particular character.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// index - Zero-based index of the character.
// Return value:
// The font size of the particular character, measured in points (about
// 1/72 inch).
// This is the typographic size of the font (so called "em size").
//
DLLEXPORT double STDCALL FPDFText_GetFontSize(FPDF_TEXTPAGE text_page,
int index);
// Function: FPDFText_GetCharBox
// Get bounding box of a particular character.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// index - Zero-based index of the character.
// left - Pointer to a double number receiving left position
// of the character box.
// right - Pointer to a double number receiving right position
// of the character box.
// bottom - Pointer to a double number receiving bottom position
// of the character box.
// top - Pointer to a double number receiving top position of
// the character box.
// Return Value:
// None.
// Comments:
// All positions are measured in PDF "user space".
//
DLLEXPORT void STDCALL FPDFText_GetCharBox(FPDF_TEXTPAGE text_page,
int index,
double* left,
double* right,
double* bottom,
double* top);
// Function: FPDFText_GetCharIndexAtPos
// Get the index of a character at or nearby a certain position on the
// page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// x - X position in PDF "user space".
// y - Y position in PDF "user space".
// xTolerance - An x-axis tolerance value for character hit
// detection, in point unit.
// yTolerance - A y-axis tolerance value for character hit
// detection, in point unit.
// Return Value:
// The zero-based index of the character at, or nearby the point (x,y).
// If there is no character at or nearby the point, return value will
// be -1.
// If an error occurs, -3 will be returned.
//
DLLEXPORT int STDCALL FPDFText_GetCharIndexAtPos(FPDF_TEXTPAGE text_page,
double x,
double y,
double xTolerance,
double yTolerance);
// Function: FPDFText_GetText
// Extract unicode text string from the page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// start_index - Index for the start characters.
// count - Number of characters to be extracted.
// result - A buffer (allocated by application) receiving the
// extracted unicodes.
// The size of the buffer must be able to hold the
// number of characters plus a terminator.
// Return Value:
// Number of characters written into the result buffer, including the
// trailing terminator.
// Comments:
// This function ignores characters without unicode information.
//
DLLEXPORT int STDCALL FPDFText_GetText(FPDF_TEXTPAGE text_page,
int start_index,
int count,
unsigned short* result);
// Function: FPDFText_CountRects
// Count number of rectangular areas occupied by a segment of texts.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// start_index - Index for the start characters.
// count - Number of characters.
// Return value:
// Number of rectangles. Zero for error.
// Comments:
// This function, along with FPDFText_GetRect can be used by
// applications to detect the position
// on the page for a text segment, so proper areas can be highlighted
// or something.
// FPDFTEXT will automatically merge small character boxes into bigger
// one if those characters
// are on the same line and use same font settings.
//
DLLEXPORT int STDCALL FPDFText_CountRects(FPDF_TEXTPAGE text_page,
int start_index,
int count);
// Function: FPDFText_GetRect
// Get a rectangular area from the result generated by
// FPDFText_CountRects.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// rect_index - Zero-based index for the rectangle.
// left - Pointer to a double value receiving the rectangle
// left boundary.
// top - Pointer to a double value receiving the rectangle
// top boundary.
// right - Pointer to a double value receiving the rectangle
// right boundary.
// bottom - Pointer to a double value receiving the rectangle
// bottom boundary.
// Return Value:
// None.
//
DLLEXPORT void STDCALL FPDFText_GetRect(FPDF_TEXTPAGE text_page,
int rect_index,
double* left,
double* top,
double* right,
double* bottom);
// Function: FPDFText_GetBoundedText
// Extract unicode text within a rectangular boundary on the page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// left - Left boundary.
// top - Top boundary.
// right - Right boundary.
// bottom - Bottom boundary.
// buffer - A unicode buffer.
// buflen - Number of characters (not bytes) for the buffer,
// excluding an additional terminator.
// Return Value:
// If buffer is NULL or buflen is zero, return number of characters
// (not bytes) of text present within
// the rectangle, excluding a terminating NUL. Generally you should
// pass a buffer at least one larger
// than this if you want a terminating NUL, which will be provided if
// space is available.
// Otherwise, return number of characters copied into the buffer,
// including the terminating NUL
// when space for it is available.
// Comment:
// If the buffer is too small, as much text as will fit is copied into
// it.
//
DLLEXPORT int STDCALL FPDFText_GetBoundedText(FPDF_TEXTPAGE text_page,
double left,
double top,
double right,
double bottom,
unsigned short* buffer,
int buflen);
// Flags used by FPDFText_FindStart function.
#define FPDF_MATCHCASE \
0x00000001 // If not set, it will not match case by default.
#define FPDF_MATCHWHOLEWORD \
0x00000002 // If not set, it will not match the whole word by default.
// Function: FPDFText_FindStart
// Start a search.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// findwhat - A unicode match pattern.
// flags - Option flags.
// start_index - Start from this character. -1 for end of the page.
// Return Value:
// A handle for the search context. FPDFText_FindClose must be called
// to release this handle.
//
DLLEXPORT FPDF_SCHHANDLE STDCALL FPDFText_FindStart(FPDF_TEXTPAGE text_page,
FPDF_WIDESTRING findwhat,
unsigned long flags,
int start_index);
// Function: FPDFText_FindNext
// Search in the direction from page start to end.
// Parameters:
// handle - A search context handle returned by
// FPDFText_FindStart.
// Return Value:
// Whether a match is found.
//
DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindNext(FPDF_SCHHANDLE handle);
// Function: FPDFText_FindPrev
// Search in the direction from page end to start.
// Parameters:
// handle - A search context handle returned by
// FPDFText_FindStart.
// Return Value:
// Whether a match is found.
//
DLLEXPORT FPDF_BOOL STDCALL FPDFText_FindPrev(FPDF_SCHHANDLE handle);
// Function: FPDFText_GetSchResultIndex
// Get the starting character index of the search result.
// Parameters:
// handle - A search context handle returned by
// FPDFText_FindStart.
// Return Value:
// Index for the starting character.
//
DLLEXPORT int STDCALL FPDFText_GetSchResultIndex(FPDF_SCHHANDLE handle);
// Function: FPDFText_GetSchCount
// Get the number of matched characters in the search result.
// Parameters:
// handle - A search context handle returned by
// FPDFText_FindStart.
// Return Value:
// Number of matched characters.
//
DLLEXPORT int STDCALL FPDFText_GetSchCount(FPDF_SCHHANDLE handle);
// Function: FPDFText_FindClose
// Release a search context.
// Parameters:
// handle - A search context handle returned by
// FPDFText_FindStart.
// Return Value:
// None.
//
DLLEXPORT void STDCALL FPDFText_FindClose(FPDF_SCHHANDLE handle);
// Function: FPDFLink_LoadWebLinks
// Prepare information about weblinks in a page.
// Parameters:
// text_page - Handle to a text page information structure.
// Returned by FPDFText_LoadPage function.
// Return Value:
// A handle to the page's links information structure.
// NULL if something goes wrong.
// Comments:
// Weblinks are those links implicitly embedded in PDF pages. PDF also
// has a type of
// annotation called "link", FPDFTEXT doesn't deal with that kind of
// link.
// FPDFTEXT weblink feature is useful for automatically detecting links
// in the page
// contents. For example, things like "http://www.foxitsoftware.com"
// will be detected,
// so applications can allow user to click on those characters to
// activate the link,
// even the PDF doesn't come with link annotations.
//
// FPDFLink_CloseWebLinks must be called to release resources.
//
DLLEXPORT FPDF_PAGELINK STDCALL FPDFLink_LoadWebLinks(FPDF_TEXTPAGE text_page);
// Function: FPDFLink_CountWebLinks
// Count number of detected web links.
// Parameters:
// link_page - Handle returned by FPDFLink_LoadWebLinks.
// Return Value:
// Number of detected web links.
//
DLLEXPORT int STDCALL FPDFLink_CountWebLinks(FPDF_PAGELINK link_page);
// Function: FPDFLink_GetURL
// Fetch the URL information for a detected web link.
// Parameters:
// link_page - Handle returned by FPDFLink_LoadWebLinks.
// link_index - Zero-based index for the link.
// buffer - A unicode buffer.
// buflen - Number of characters (not bytes) for the buffer,
// including an additional terminator.
// Return Value:
// If buffer is NULL or buflen is zero, return number of characters
// (not bytes and an additional terminator is also counted) needed,
// otherwise, return number of characters copied into the buffer.
//
DLLEXPORT int STDCALL FPDFLink_GetURL(FPDF_PAGELINK link_page,
int link_index,
unsigned short* buffer,
int buflen);
// Function: FPDFLink_CountRects
// Count number of rectangular areas for the link.
// Parameters:
// link_page - Handle returned by FPDFLink_LoadWebLinks.
// link_index - Zero-based index for the link.
// Return Value:
// Number of rectangular areas for the link.
//
DLLEXPORT int STDCALL FPDFLink_CountRects(FPDF_PAGELINK link_page,
int link_index);
// Function: FPDFLink_GetRect
// Fetch the boundaries of a rectangle for a link.
// Parameters:
// link_page - Handle returned by FPDFLink_LoadWebLinks.
// link_index - Zero-based index for the link.
// rect_index - Zero-based index for a rectangle.
// left - Pointer to a double value receiving the rectangle
// left boundary.
// top - Pointer to a double value receiving the rectangle
// top boundary.
// right - Pointer to a double value receiving the rectangle
// right boundary.
// bottom - Pointer to a double value receiving the rectangle
// bottom boundary.
// Return Value:
// None.
//
DLLEXPORT void STDCALL FPDFLink_GetRect(FPDF_PAGELINK link_page,
int link_index,
int rect_index,
double* left,
double* top,
double* right,
double* bottom);
// Function: FPDFLink_CloseWebLinks
// Release resources used by weblink feature.
// Parameters:
// link_page - Handle returned by FPDFLink_LoadWebLinks.
// Return Value:
// None.
//
DLLEXPORT void STDCALL FPDFLink_CloseWebLinks(FPDF_PAGELINK link_page);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_TEXT_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef PUBLIC_FPDF_TRANSFORMPAGE_H_
#define PUBLIC_FPDF_TRANSFORMPAGE_H_
#include "fpdfview.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void* FPDF_PAGEARCSAVER;
typedef void* FPDF_PAGEARCLOADER;
/**
* Set "MediaBox" entry to the page dictionary.
* @param[in] page - Handle to a page.
* @param[in] left - The left of the rectangle.
* @param[in] bottom - The bottom of the rectangle.
* @param[in] right - The right of the rectangle.
* @param[in] top - The top of the rectangle.
* @retval None.
*/
DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page,
float left,
float bottom,
float right,
float top);
/**
* Set "CropBox" entry to the page dictionary.
* @param[in] page - Handle to a page.
* @param[in] left - The left of the rectangle.
* @param[in] bottom - The bottom of the rectangle.
* @param[in] right - The right of the rectangle.
* @param[in] top - The top of the rectangle.
* @retval None.
*/
DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page,
float left,
float bottom,
float right,
float top);
/** Get "MediaBox" entry from the page dictionary.
* @param[in] page - Handle to a page.
* @param[in] left - Pointer to a double value receiving the left of the
* rectangle.
* @param[in] bottom - Pointer to a double value receiving the bottom of the
* rectangle.
* @param[in] right - Pointer to a double value receiving the right of the
* rectangle.
* @param[in] top - Pointer to a double value receiving the top of the
* rectangle.
* @retval True if success,else fail.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page,
float* left,
float* bottom,
float* right,
float* top);
/** Get "CropBox" entry from the page dictionary.
* @param[in] page - Handle to a page.
* @param[in] left - Pointer to a double value receiving the left of the
* rectangle.
* @param[in] bottom - Pointer to a double value receiving the bottom of the
* rectangle.
* @param[in] right - Pointer to a double value receiving the right of the
* rectangle.
* @param[in] top - Pointer to a double value receiving the top of the
* rectangle.
* @retval True if success,else fail.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page,
float* left,
float* bottom,
float* right,
float* top);
/**
* Transform the whole page with a specified matrix, then clip the page content
* region.
*
* @param[in] page - A page handle.
* @param[in] matrix - The transform matrix.
* @param[in] clipRect - A rectangle page area to be clipped.
* @Note. This function will transform the whole page, and would take effect to
* all the objects in the page.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page,
FS_MATRIX* matrix,
FS_RECTF* clipRect);
/**
* Transform (scale, rotate, shear, move) the clip path of page object.
* @param[in] page_object - Handle to a page object. Returned by
* FPDFPageObj_NewImageObj.
* @param[in] a - The coefficient "a" of the matrix.
* @param[in] b - The coefficient "b" of the matrix.
* @param[in] c - The coefficient "c" of the matrix.
* @param[in] d - The coefficient "d" of the matrix.
* @param[in] e - The coefficient "e" of the matrix.
* @param[in] f - The coefficient "f" of the matrix.
* @retval None.
*/
DLLEXPORT void STDCALL
FPDFPageObj_TransformClipPath(FPDF_PAGEOBJECT page_object,
double a,
double b,
double c,
double d,
double e,
double f);
/**
* Create a new clip path, with a rectangle inserted.
*
* @param[in] left - The left of the clip box.
* @param[in] bottom - The bottom of the clip box.
* @param[in] right - The right of the clip box.
* @param[in] top - The top of the clip box.
* @retval a handle to the clip path.
*/
DLLEXPORT FPDF_CLIPPATH STDCALL FPDF_CreateClipPath(float left,
float bottom,
float right,
float top);
/**
* Destroy the clip path.
*
* @param[in] clipPath - A handle to the clip path.
* Destroy the clip path.
* @retval None.
*/
DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath);
/**
* Clip the page content, the page content that outside the clipping region
* become invisible.
*
* @param[in] page - A page handle.
* @param[in] clipPath - A handle to the clip path.
* @Note. A clip path will be inserted before the page content stream or content
* array. In this way, the page content will be clipped
* by this clip path.
*/
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,
FPDF_CLIPPATH clipPath);
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDF_TRANSFORMPAGE_H_
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// NOTE: External docs refer to this file as "fpdfview.h", so do not rename
// despite lack of consitency with other public files.
#ifndef PUBLIC_FPDFVIEW_H_
#define PUBLIC_FPDFVIEW_H_
#if defined(_WIN32) && !defined(__WINDOWS__)
#include <windows.h>
#endif
#ifdef PDF_ENABLE_XFA
// TODO: remove the #define when XFA is officially in pdfium
#define PDF_USE_XFA
#endif // PDF_ENABLE_XFA
// PDF types
typedef void* FPDF_ACTION;
typedef void* FPDF_BITMAP;
typedef void* FPDF_BOOKMARK;
typedef void* FPDF_CLIPPATH;
typedef void* FPDF_DEST;
typedef void* FPDF_DOCSCHHANDLE;
typedef void* FPDF_DOCUMENT;
typedef void* FPDF_FONT;
typedef void* FPDF_HMODULE;
typedef void* FPDF_LINK;
typedef void* FPDF_MODULEMGR;
typedef void* FPDF_PAGE;
typedef void* FPDF_PAGELINK;
typedef void* FPDF_PAGEOBJECT; // Page object(text, path, etc)
typedef void* FPDF_PAGERANGE;
typedef void* FPDF_PATH;
typedef void* FPDF_SCHHANDLE;
typedef void* FPDF_TEXTPAGE;
#ifdef PDF_ENABLE_XFA
typedef void* FPDF_STRINGHANDLE;
typedef void* FPDF_WIDGET;
#endif // PDF_ENABLE_XFA
// Basic data types
typedef int FPDF_BOOL;
typedef int FPDF_ERROR;
typedef unsigned long FPDF_DWORD;
typedef float FS_FLOAT;
#ifdef PDF_ENABLE_XFA
typedef void* FPDF_LPVOID;
typedef void const* FPDF_LPCVOID;
typedef char const* FPDF_LPCSTR;
typedef int FPDF_RESULT;
#endif
// Duplex types
typedef enum _FPDF_DUPLEXTYPE_ {
DuplexUndefined = 0,
Simplex,
DuplexFlipShortEdge,
DuplexFlipLongEdge
} FPDF_DUPLEXTYPE;
// String types
typedef unsigned short FPDF_WCHAR;
typedef unsigned char const* FPDF_LPCBYTE;
// FPDFSDK may use three types of strings: byte string, wide string (UTF-16LE
// encoded), and platform dependent string
typedef const char* FPDF_BYTESTRING;
// FPDFSDK always uses UTF-16LE encoded wide strings, each character uses 2
// bytes (except surrogation), with the low byte first.
typedef const unsigned short* FPDF_WIDESTRING;
#ifdef PDF_ENABLE_XFA
// Structure for a byte string.
// Note, a byte string commonly means a UTF-16LE formated string.
typedef struct _FPDF_BSTR {
// String buffer.
char* str;
// Length of the string, in bytes.
int len;
} FPDF_BSTR;
#endif // PDF_ENABLE_XFA
// For Windows programmers: In most cases it's OK to treat FPDF_WIDESTRING as a
// Windows unicode string, however, special care needs to be taken if you
// expect to process Unicode larger than 0xffff.
//
// For Linux/Unix programmers: most compiler/library environments use 4 bytes
// for a Unicode character, and you have to convert between FPDF_WIDESTRING and
// system wide string by yourself.
#ifdef _WIN32_WCE
typedef const unsigned short* FPDF_STRING;
#else
typedef const char* FPDF_STRING;
#endif
// Matrix for transformation.
typedef struct _FS_MATRIX_ {
float a;
float b;
float c;
float d;
float e;
float f;
} FS_MATRIX;
// Rectangle area(float) in device or page coordinate system.
typedef struct _FS_RECTF_ {
// The x-coordinate of the left-top corner.
float left;
// The y-coordinate of the left-top corner.
float top;
// The x-coordinate of the right-bottom corner.
float right;
// The y-coordinate of the right-bottom corner.
float bottom;
} * FS_LPRECTF, FS_RECTF;
// Const Pointer to FS_RECTF structure.
typedef const FS_RECTF* FS_LPCRECTF;
#if defined(_WIN32) && defined(FPDFSDK_EXPORTS)
// On Windows system, functions are exported in a DLL
#define DLLEXPORT __declspec(dllexport)
#define STDCALL __stdcall
#else
#define DLLEXPORT
#define STDCALL
#endif
// Exported Functions
#ifdef __cplusplus
extern "C" {
#endif
// Function: FPDF_InitLibrary
// Initialize the FPDFSDK library
// Parameters:
// None
// Return value:
// None.
// Comments:
// Convenience function to call FPDF_InitLibraryWithConfig() for
// backwards comatibility purposes.
DLLEXPORT void STDCALL FPDF_InitLibrary();
// Process-wide options for initializing the library.
typedef struct FPDF_LIBRARY_CONFIG_ {
// Version number of the interface. Currently must be 2.
int version;
// Array of paths to scan in place of the defaults when using built-in
// FXGE font loading code. The array is terminated by a NULL pointer.
// The Array may be NULL itself to use the default paths. May be ignored
// entirely depending upon the platform.
const char** m_pUserFontPaths;
// Version 2.
// pointer to the v8::Isolate to use, or NULL to force PDFium to create one.
void* m_pIsolate;
// The embedder data slot to use in the v8::Isolate to store PDFium's
// per-isolate data. The value needs to be between 0 and
// v8::Internals::kNumIsolateDataLots (exclusive). Note that 0 is fine
// for most embedders.
unsigned int m_v8EmbedderSlot;
} FPDF_LIBRARY_CONFIG;
// Function: FPDF_InitLibraryWithConfig
// Initialize the FPDFSDK library
// Parameters:
// config - configuration information as above.
// Return value:
// None.
// Comments:
// You have to call this function before you can call any PDF
// processing functions.
DLLEXPORT void STDCALL FPDF_InitLibraryWithConfig(
const FPDF_LIBRARY_CONFIG* config);
// Function: FPDF_DestroyLibary
// Release all resources allocated by the FPDFSDK library.
// Parameters:
// None.
// Return value:
// None.
// Comments:
// You can call this function to release all memory blocks allocated by
// the library.
// After this function is called, you should not call any PDF
// processing functions.
DLLEXPORT void STDCALL FPDF_DestroyLibrary();
// Policy for accessing the local machine time.
#define FPDF_POLICY_MACHINETIME_ACCESS 0
// Function: FPDF_SetSandBoxPolicy
// Set the policy for the sandbox environment.
// Parameters:
// policy - The specified policy for setting, for example:
// FPDF_POLICY_MACHINETIME_ACCESS.
// enable - True to enable, false to disable the policy.
// Return value:
// None.
DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy,
FPDF_BOOL enable);
// Function: FPDF_LoadDocument
// Open and load a PDF document.
// Parameters:
// file_path - Path to the PDF file (including extension).
// password - A string used as the password for the PDF file.
// If no password is needed, empty or NULL can be used.
// Return value:
// A handle to the loaded document, or NULL on failure.
// Comments:
// Loaded document can be closed by FPDF_CloseDocument().
// If this function fails, you can use FPDF_GetLastError() to retrieve
// the reason why it failed.
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
FPDF_BYTESTRING password);
// Function: FPDF_LoadMemDocument
// Open and load a PDF document from memory.
// Parameters:
// data_buf - Pointer to a buffer containing the PDF document.
// size - Number of bytes in the PDF document.
// password - A string used as the password for the PDF file.
// If no password is needed, empty or NULL can be used.
// Return value:
// A handle to the loaded document, or NULL on failure.
// Comments:
// The memory buffer must remain valid when the document is open.
// The loaded document can be closed by FPDF_CloseDocument.
// If this function fails, you can use FPDF_GetLastError() to retrieve
// the reason why it failed.
// Notes:
// If PDFium is built with the XFA module, the application should call
// FPDF_LoadXFA() function after the PDF document loaded to support XFA
// fields defined in the fpdfformfill.h file.
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
int size,
FPDF_BYTESTRING password);
// Structure for custom file access.
typedef struct {
// File length, in bytes.
unsigned long m_FileLen;
// A function pointer for getting a block of data from a specific position.
// Position is specified by byte offset from the beginning of the file.
// The position and size will never go out of range of the file length.
// It may be possible for FPDFSDK to call this function multiple times for
// the same position.
// Return value: should be non-zero if successful, zero for error.
int (*m_GetBlock)(void* param,
unsigned long position,
unsigned char* pBuf,
unsigned long size);
// A custom pointer for all implementation specific data. This pointer will
// be used as the first parameter to the m_GetBlock callback.
void* m_Param;
} FPDF_FILEACCESS;
#ifdef PDF_ENABLE_XFA
/**
* @brief Structure for file reading or writing (I/O).
*
* @note This is a handler and should be implemented by callers.
*/
typedef struct _FPDF_FILEHANDLER {
/**
* @brief User-defined data.
* @note Callers can use this field to track controls.
*/
FPDF_LPVOID clientData;
/**
* @brief Callback function to release the current file stream object.
*
* @param[in] clientData Pointer to user-defined data.
*
* @return None.
*/
void (*Release)(FPDF_LPVOID clientData);
/**
* @brief Callback function to retrieve the current file stream size.
*
* @param[in] clientData Pointer to user-defined data.
*
* @return Size of file stream.
*/
FPDF_DWORD (*GetSize)(FPDF_LPVOID clientData);
/**
* @brief Callback function to read data from the current file stream.
*
* @param[in] clientData Pointer to user-defined data.
* @param[in] offset Offset position starts from the beginning of file
* stream. This parameter indicates reading position.
* @param[in] buffer Memory buffer to store data which are read from
* file stream. This parameter should not be <b>NULL</b>.
* @param[in] size Size of data which should be read from file
* stream, in bytes. The buffer indicated by the parameter <i>buffer</i>
* should be enough to store specified data.
*
* @return 0 for success, other value for failure.
*/
FPDF_RESULT (*ReadBlock)(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPVOID buffer, FPDF_DWORD size);
/**
* @brief Callback function to write data into the current file stream.
*
* @param[in] clientData Pointer to user-defined data.
* @param[in] offset Offset position starts from the beginning of file
* stream. This parameter indicates writing position.
* @param[in] buffer Memory buffer contains data which is written into
* file stream. This parameter should not be <b>NULL</b>.
* @param[in] size Size of data which should be written into file
* stream, in bytes.
*
* @return 0 for success, other value for failure.
*/
FPDF_RESULT (*WriteBlock)(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPCVOID buffer, FPDF_DWORD size);
/**
* @brief Callback function to flush all internal accessing buffers.
*
* @param[in] clientData Pointer to user-defined data.
*
* @return 0 for success, other value for failure.
*/
FPDF_RESULT (*Flush)(FPDF_LPVOID clientData);
/**
* @brief Callback function to change file size.
*
* @details This function is called under writing mode usually. Implementer
* can determine whether to realize it based on application requests.
*
* @param[in] clientData Pointer to user-defined data.
* @param[in] size New size of file stream, in bytes.
*
* @return 0 for success, other value for failure.
*/
FPDF_RESULT (*Truncate)(FPDF_LPVOID clientData, FPDF_DWORD size);
} FPDF_FILEHANDLER, *FPDF_LPFILEHANDLER;
#endif
// Function: FPDF_LoadCustomDocument
// Load PDF document from a custom access descriptor.
// Parameters:
// pFileAccess - A structure for accessing the file.
// password - Optional password for decrypting the PDF file.
// Return value:
// A handle to the loaded document, or NULL on failure.
// Comments:
// The application must keep the file resources valid until the PDF
// document is closed.
//
// The loaded document can be closed with FPDF_CloseDocument.
// Notes:
// If PDFium is built with the XFA module, the application should call
// FPDF_LoadXFA() function after the PDF document loaded to support XFA
// fields defined in the fpdfformfill.h file.
DLLEXPORT FPDF_DOCUMENT STDCALL
FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess, FPDF_BYTESTRING password);
// Function: FPDF_GetFileVersion
// Get the file version of the given PDF document.
// Parameters:
// doc - Handle to a document.
// fileVersion - The PDF file version. File version: 14 for 1.4, 15
// for 1.5, ...
// Return value:
// True if succeeds, false otherwise.
// Comments:
// If the document was created by FPDF_CreateNewDocument,
// then this function will always fail.
DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc,
int* fileVersion);
#define FPDF_ERR_SUCCESS 0 // No error.
#define FPDF_ERR_UNKNOWN 1 // Unknown error.
#define FPDF_ERR_FILE 2 // File not found or could not be opened.
#define FPDF_ERR_FORMAT 3 // File not in PDF format or corrupted.
#define FPDF_ERR_PASSWORD 4 // Password required or incorrect password.
#define FPDF_ERR_SECURITY 5 // Unsupported security scheme.
#define FPDF_ERR_PAGE 6 // Page not found or content error.
#ifdef PDF_ENABLE_XFA
#define FPDF_ERR_XFALOAD 7 // Load XFA error.
#define FPDF_ERR_XFALAYOUT 8 // Layout XFA error.
#endif // PDF_ENABLE_XFA
// Function: FPDF_GetLastError
// Get last error code when a function fails.
// Parameters:
// None.
// Return value:
// A 32-bit integer indicating error code as defined above.
// Comments:
// If the previous SDK call succeeded, the return value of this
// function is not defined.
DLLEXPORT unsigned long STDCALL FPDF_GetLastError();
// Function: FPDF_GetDocPermission
// Get file permission flags of the document.
// Parameters:
// document - Handle to a document. Returned by FPDF_LoadDocument.
// Return value:
// A 32-bit integer indicating permission flags. Please refer to the
// PDF Reference for detailed descriptions. If the document is not
// protected, 0xffffffff will be returned.
DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document);
// Function: FPDF_GetSecurityHandlerRevision
// Get the revision for the security handler.
// Parameters:
// document - Handle to a document. Returned by FPDF_LoadDocument.
// Return value:
// The security handler revision number. Please refer to the PDF
// Reference for a detailed description. If the document is not
// protected, -1 will be returned.
DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document);
// Function: FPDF_GetPageCount
// Get total number of pages in the document.
// Parameters:
// document - Handle to document. Returned by FPDF_LoadDocument.
// Return value:
// Total number of pages in the document.
DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document);
// Function: FPDF_LoadPage
// Load a page inside the document.
// Parameters:
// document - Handle to document. Returned by FPDF_LoadDocument
// page_index - Index number of the page. 0 for the first page.
// Return value:
// A handle to the loaded page, or NULL if page load fails.
// Comments:
// The loaded page can be rendered to devices using FPDF_RenderPage.
// The loaded page can be closed using FPDF_ClosePage.
DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document,
int page_index);
// Function: FPDF_GetPageWidth
// Get page width.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage.
// Return value:
// Page width (excluding non-displayable area) measured in points.
// One point is 1/72 inch (around 0.3528 mm).
DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page);
// Function: FPDF_GetPageHeight
// Get page height.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage.
// Return value:
// Page height (excluding non-displayable area) measured in points.
// One point is 1/72 inch (around 0.3528 mm)
DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page);
// Function: FPDF_GetPageSizeByIndex
// Get the size of the page at the given index.
// Parameters:
// document - Handle to document. Returned by FPDF_LoadDocument.
// page_index - Page index, zero for the first page.
// width - Pointer to a double to receive the page width
// (in points).
// height - Pointer to a double to receive the page height
// (in points).
// Return value:
// Non-zero for success. 0 for error (document or page not found).
DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document,
int page_index,
double* width,
double* height);
// Page rendering flags. They can be combined with bit-wise OR.
//
// Set if annotations are to be rendered.
#define FPDF_ANNOT 0x01
// Set if using text rendering optimized for LCD display.
#define FPDF_LCD_TEXT 0x02
// Don't use the native text output available on some platforms
#define FPDF_NO_NATIVETEXT 0x04
// Grayscale output.
#define FPDF_GRAYSCALE 0x08
// Set if you want to get some debug info.
#define FPDF_DEBUG_INFO 0x80
// Set if you don't want to catch exceptions.
#define FPDF_NO_CATCH 0x100
// Limit image cache size.
#define FPDF_RENDER_LIMITEDIMAGECACHE 0x200
// Always use halftone for image stretching.
#define FPDF_RENDER_FORCEHALFTONE 0x400
// Render for printing.
#define FPDF_PRINTING 0x800
// Set to disable anti-aliasing on text.
#define FPDF_RENDER_NO_SMOOTHTEXT 0x1000
// Set to disable anti-aliasing on images.
#define FPDF_RENDER_NO_SMOOTHIMAGE 0x2000
// Set to disable anti-aliasing on paths.
#define FPDF_RENDER_NO_SMOOTHPATH 0x4000
// Set whether to render in a reverse Byte order, this flag is only used when
// rendering to a bitmap.
#define FPDF_REVERSE_BYTE_ORDER 0x10
#ifdef _WIN32
// Function: FPDF_RenderPage
// Render contents of a page to a device (screen, bitmap, or printer).
// This function is only supported on Windows.
// Parameters:
// dc - Handle to the device context.
// page - Handle to the page. Returned by FPDF_LoadPage.
// start_x - Left pixel position of the display area in
// device coordinates.
// start_y - Top pixel position of the display area in device
// coordinates.
// size_x - Horizontal size (in pixels) for displaying the page.
// size_y - Vertical size (in pixels) for displaying the page.
// rotate - Page orientation:
// 0 (normal)
// 1 (rotated 90 degrees clockwise)
// 2 (rotated 180 degrees)
// 3 (rotated 90 degrees counter-clockwise)
// flags - 0 for normal display, or combination of flags
// defined above.
// Return value:
// None.
DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc,
FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags);
#endif
// Function: FPDF_RenderPageBitmap
// Render contents of a page to a device independent bitmap.
// Parameters:
// bitmap - Handle to the device independent bitmap (as the
// output buffer). The bitmap handle can be created
// by FPDFBitmap_Create.
// page - Handle to the page. Returned by FPDF_LoadPage
// start_x - Left pixel position of the display area in
// bitmap coordinates.
// start_y - Top pixel position of the display area in bitmap
// coordinates.
// size_x - Horizontal size (in pixels) for displaying the page.
// size_y - Vertical size (in pixels) for displaying the page.
// rotate - Page orientation:
// 0 (normal)
// 1 (rotated 90 degrees clockwise)
// 2 (rotated 180 degrees)
// 3 (rotated 90 degrees counter-clockwise)
// flags - 0 for normal display, or combination of flags
// defined above.
// Return value:
// None.
DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap,
FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int flags);
// Function: FPDF_ClosePage
// Close a loaded PDF page.
// Parameters:
// page - Handle to the loaded page.
// Return value:
// None.
DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page);
// Function: FPDF_CloseDocument
// Close a loaded PDF document.
// Parameters:
// document - Handle to the loaded document.
// Return value:
// None.
DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document);
// Function: FPDF_DeviceToPage
// Convert the screen coordinates of a point to page coordinates.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage.
// start_x - Left pixel position of the display area in
// device coordinates.
// start_y - Top pixel position of the display area in device
// coordinates.
// size_x - Horizontal size (in pixels) for displaying the page.
// size_y - Vertical size (in pixels) for displaying the page.
// rotate - Page orientation:
// 0 (normal)
// 1 (rotated 90 degrees clockwise)
// 2 (rotated 180 degrees)
// 3 (rotated 90 degrees counter-clockwise)
// device_x - X value in device coordinates to be converted.
// device_y - Y value in device coordinates to be converted.
// page_x - A pointer to a double receiving the converted X
// value in page coordinates.
// page_y - A pointer to a double receiving the converted Y
// value in page coordinates.
// Return value:
// None.
// Comments:
// The page coordinate system has its origin at the left-bottom corner
// of the page, with the X-axis on the bottom going to the right, and
// the Y-axis on the left side going up.
//
// NOTE: this coordinate system can be altered when you zoom, scroll,
// or rotate a page, however, a point on the page should always have
// the same coordinate values in the page coordinate system.
//
// The device coordinate system is device dependent. For screen device,
// its origin is at the left-top corner of the window. However this
// origin can be altered by the Windows coordinate transformation
// utilities.
//
// You must make sure the start_x, start_y, size_x, size_y
// and rotate parameters have exactly same values as you used in
// the FPDF_RenderPage() function call.
DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
int device_x,
int device_y,
double* page_x,
double* page_y);
// Function: FPDF_PageToDevice
// Convert the page coordinates of a point to screen coordinates.
// Parameters:
// page - Handle to the page. Returned by FPDF_LoadPage.
// start_x - Left pixel position of the display area in
// device coordinates.
// start_y - Top pixel position of the display area in device
// coordinates.
// size_x - Horizontal size (in pixels) for displaying the page.
// size_y - Vertical size (in pixels) for displaying the page.
// rotate - Page orientation:
// 0 (normal)
// 1 (rotated 90 degrees clockwise)
// 2 (rotated 180 degrees)
// 3 (rotated 90 degrees counter-clockwise)
// page_x - X value in page coordinates.
// page_y - Y value in page coordinate.
// device_x - A pointer to an integer receiving the result X
// value in device coordinates.
// device_y - A pointer to an integer receiving the result Y
// value in device coordinates.
// Return value:
// None.
// Comments:
// See comments for FPDF_DeviceToPage().
DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page,
int start_x,
int start_y,
int size_x,
int size_y,
int rotate,
double page_x,
double page_y,
int* device_x,
int* device_y);
// Function: FPDFBitmap_Create
// Create a device independent bitmap (FXDIB).
// Parameters:
// width - The number of pixels in width for the bitmap.
// Must be greater than 0.
// height - The number of pixels in height for the bitmap.
// Must be greater than 0.
// alpha - A flag indicating whether the alpha channel is used.
// Non-zero for using alpha, zero for not using.
// Return value:
// The created bitmap handle, or NULL if a parameter error or out of
// memory.
// Comments:
// The bitmap always uses 4 bytes per pixel. The first byte is always
// double word aligned.
//
// The byte order is BGRx (the last byte unused if no alpha channel) or
// BGRA.
//
// The pixels in a horizontal line are stored side by side, with the
// left most pixel stored first (with lower memory address).
// Each line uses width * 4 bytes.
//
// Lines are stored one after another, with the top most line stored
// first. There is no gap between adjacent lines.
//
// This function allocates enough memory for holding all pixels in the
// bitmap, but it doesn't initialize the buffer. Applications can use
// FPDFBitmap_FillRect to fill the bitmap using any color.
DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width,
int height,
int alpha);
// More DIB formats
// Gray scale bitmap, one byte per pixel.
#define FPDFBitmap_Gray 1
// 3 bytes per pixel, byte order: blue, green, red.
#define FPDFBitmap_BGR 2
// 4 bytes per pixel, byte order: blue, green, red, unused.
#define FPDFBitmap_BGRx 3
// 4 bytes per pixel, byte order: blue, green, red, alpha.
#define FPDFBitmap_BGRA 4
// Function: FPDFBitmap_CreateEx
// Create a device independent bitmap (FXDIB)
// Parameters:
// width - The number of pixels in width for the bitmap.
// Must be greater than 0.
// height - The number of pixels in height for the bitmap.
// Must be greater than 0.
// format - A number indicating for bitmap format, as defined
// above.
// first_scan - A pointer to the first byte of the first line if
// using an external buffer. If this parameter is NULL,
// then the a new buffer will be created.
// stride - Number of bytes for each scan line, for external
// buffer only.
// Return value:
// The bitmap handle, or NULL if parameter error or out of memory.
// Comments:
// Similar to FPDFBitmap_Create function, but allows for more formats
// and an external buffer is supported. The bitmap created by this
// function can be used in any place that a FPDF_BITMAP handle is
// required.
//
// If an external buffer is used, then the application should destroy
// the buffer by itself. FPDFBitmap_Destroy function will not destroy
// the buffer.
DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_CreateEx(int width,
int height,
int format,
void* first_scan,
int stride);
// Function: FPDFBitmap_FillRect
// Fill a rectangle in a bitmap.
// Parameters:
// bitmap - The handle to the bitmap. Returned by
// FPDFBitmap_Create.
// left - The left position. Starting from 0 at the
// left-most pixel.
// top - The top position. Starting from 0 at the
// top-most line.
// width - Width in pixels to be filled.
// height - Height in pixels to be filled.
// color - A 32-bit value specifing the color, in 8888 ARGB
// format.
// Return value:
// None.
// Comments:
// This function sets the color and (optionally) alpha value in the
// specified region of the bitmap.
//
// NOTE: If the alpha channel is used, this function does NOT
// composite the background with the source color, instead the
// background will be replaced by the source color and the alpha.
//
// If the alpha channel is not used, the alpha parameter is ignored.
DLLEXPORT void STDCALL FPDFBitmap_FillRect(FPDF_BITMAP bitmap,
int left,
int top,
int width,
int height,
FPDF_DWORD color);
// Function: FPDFBitmap_GetBuffer
// Get data buffer of a bitmap.
// Parameters:
// bitmap - Handle to the bitmap. Returned by FPDFBitmap_Create.
// Return value:
// The pointer to the first byte of the bitmap buffer.
// Comments:
// The stride may be more than width * number of bytes per pixel
//
// Applications can use this function to get the bitmap buffer pointer,
// then manipulate any color and/or alpha values for any pixels in the
// bitmap.
//
// The data is in BGRA format. Where the A maybe unused if alpha was
// not specified.
DLLEXPORT void* STDCALL FPDFBitmap_GetBuffer(FPDF_BITMAP bitmap);
// Function: FPDFBitmap_GetWidth
// Get width of a bitmap.
// Parameters:
// bitmap - Handle to the bitmap. Returned by FPDFBitmap_Create.
// Return value:
// The width of the bitmap in pixels.
DLLEXPORT int STDCALL FPDFBitmap_GetWidth(FPDF_BITMAP bitmap);
// Function: FPDFBitmap_GetHeight
// Get height of a bitmap.
// Parameters:
// bitmap - Handle to the bitmap. Returned by FPDFBitmap_Create.
// Return value:
// The height of the bitmap in pixels.
DLLEXPORT int STDCALL FPDFBitmap_GetHeight(FPDF_BITMAP bitmap);
// Function: FPDFBitmap_GetStride
// Get number of bytes for each line in the bitmap buffer.
// Parameters:
// bitmap - Handle to the bitmap. Returned by FPDFBitmap_Create.
// Return value:
// The number of bytes for each line in the bitmap buffer.
// Comments:
// The stride may be more than width * number of bytes per pixel.
DLLEXPORT int STDCALL FPDFBitmap_GetStride(FPDF_BITMAP bitmap);
// Function: FPDFBitmap_Destroy
// Destroy a bitmap and release all related buffers.
// Parameters:
// bitmap - Handle to the bitmap. Returned by FPDFBitmap_Create.
// Return value:
// None.
// Comments:
// This function will not destroy any external buffers provided when
// the bitmap was created.
DLLEXPORT void STDCALL FPDFBitmap_Destroy(FPDF_BITMAP bitmap);
// Function: FPDF_VIEWERREF_GetPrintScaling
// Whether the PDF document prefers to be scaled or not.
// Parameters:
// document - Handle to the loaded document.
// Return value:
// None.
DLLEXPORT FPDF_BOOL STDCALL
FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document);
// Function: FPDF_VIEWERREF_GetNumCopies
// Returns the number of copies to be printed.
// Parameters:
// document - Handle to the loaded document.
// Return value:
// The number of copies to be printed.
DLLEXPORT int STDCALL FPDF_VIEWERREF_GetNumCopies(FPDF_DOCUMENT document);
// Function: FPDF_VIEWERREF_GetPrintPageRange
// Page numbers to initialize print dialog box when file is printed.
// Parameters:
// document - Handle to the loaded document.
// Return value:
// The print page range to be used for printing.
DLLEXPORT FPDF_PAGERANGE STDCALL
FPDF_VIEWERREF_GetPrintPageRange(FPDF_DOCUMENT document);
// Function: FPDF_VIEWERREF_GetDuplex
// Returns the paper handling option to be used when printing from
// the print dialog.
// Parameters:
// document - Handle to the loaded document.
// Return value:
// The paper handling option to be used when printing.
DLLEXPORT FPDF_DUPLEXTYPE STDCALL
FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT document);
// Function: FPDF_CountNamedDests
// Get the count of named destinations in the PDF document.
// Parameters:
// document - Handle to a document
// Return value:
// The count of named destinations.
DLLEXPORT FPDF_DWORD STDCALL FPDF_CountNamedDests(FPDF_DOCUMENT document);
// Function: FPDF_GetNamedDestByName
// Get a the destination handle for the given name.
// Parameters:
// document - Handle to the loaded document.
// name - The name of a destination.
// Return value:
// The handle to the destination.
DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,
FPDF_BYTESTRING name);
// Function: FPDF_GetNamedDest
// Get the named destination by index.
// Parameters:
// document - Handle to a document
// index - The index of a named destination.
// buffer - The buffer to store the destination name,
// used as wchar_t*.
// buflen [in/out] - Size of the buffer in bytes on input,
// length of the result in bytes on output
// or -1 if the buffer is too small.
// Return value:
// The destination handle for a given index, or NULL if there is no
// named destination corresponding to |index|.
// Comments:
// Call this function twice to get the name of the named destination:
// 1) First time pass in |buffer| as NULL and get buflen.
// 2) Second time pass in allocated |buffer| and buflen to retrieve
// |buffer|, which should be used as wchar_t*.
//
// If buflen is not sufficiently large, it will be set to -1 upon
// return.
DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDest(FPDF_DOCUMENT document,
int index,
void* buffer,
long* buflen);
#ifdef PDF_ENABLE_XFA
// Function: FPDF_BStr_Init
// Helper function to initialize a byte string.
DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Init(FPDF_BSTR* str);
// Function: FPDF_BStr_Set
// Helper function to set string data.
DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Set(FPDF_BSTR* str,
FPDF_LPCSTR bstr,
int length);
// Function: FPDF_BStr_Clear
// Helper function to clear a byte string.
DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Clear(FPDF_BSTR* str);
#endif // PDF_ENABLE_XFA
#ifdef __cplusplus
}
#endif
#endif // PUBLIC_FPDFVIEW_H_
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
#ifndef ANDROID_ERRORS_H
#define ANDROID_ERRORS_H
#include <sys/types.h>
#include <errno.h>
namespace android {
// use this type to return error codes
#ifdef HAVE_MS_C_RUNTIME
typedef int status_t;
#else
typedef int32_t status_t;
#endif
/* the MS C runtime lacks a few error codes */
/*
* Error codes.
* All error codes are negative values.
*/
// Win32 #defines NO_ERROR as well. It has the same value, so there's no
// real conflict, though it's a bit awkward.
#ifdef _WIN32
# undef NO_ERROR
#endif
enum {
OK = 0, // Everything's swell.
NO_ERROR = 0, // No errors.
UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value
NO_MEMORY = -ENOMEM,
INVALID_OPERATION = -ENOSYS,
BAD_VALUE = -EINVAL,
BAD_TYPE = (UNKNOWN_ERROR + 1),
NAME_NOT_FOUND = -ENOENT,
PERMISSION_DENIED = -EPERM,
NO_INIT = -ENODEV,
ALREADY_EXISTS = -EEXIST,
DEAD_OBJECT = -EPIPE,
FAILED_TRANSACTION = (UNKNOWN_ERROR + 2),
JPARKS_BROKE_IT = -EPIPE,
#if !defined(HAVE_MS_C_RUNTIME)
BAD_INDEX = -EOVERFLOW,
NOT_ENOUGH_DATA = -ENODATA,
WOULD_BLOCK = -EWOULDBLOCK,
TIMED_OUT = -ETIMEDOUT,
UNKNOWN_TRANSACTION = -EBADMSG,
#else
BAD_INDEX = -E2BIG,
NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3),
WOULD_BLOCK = (UNKNOWN_ERROR + 4),
TIMED_OUT = (UNKNOWN_ERROR + 5),
UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6),
#endif
FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7),
};
// Restore define; enumeration is in "android" namespace, so the value defined
// there won't work for Win32 code in a different namespace.
#ifdef _WIN32
# define NO_ERROR 0L
#endif
}; // namespace android
// ---------------------------------------------------------------------------
#endif // ANDROID_ERRORS_H
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
#ifndef _LIBS_UTILS_MUTEX_H
#define _LIBS_UTILS_MUTEX_H
#include <stdint.h>
#include <sys/types.h>
#include <time.h>
#if defined(HAVE_PTHREADS)
# include <pthread.h>
#endif
#include <utils/Errors.h>
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
class Condition;
/*
* Simple mutex class. The implementation is system-dependent.
*
* The mutex must be unlocked by the thread that locked it. They are not
* recursive, i.e. the same thread can't lock it multiple times.
*/
class Mutex {
public:
enum {
PRIVATE = 0,
SHARED = 1
};
Mutex();
Mutex(const char* name);
Mutex(int type, const char* name = NULL);
~Mutex();
// lock or unlock the mutex
status_t lock();
void unlock();
// lock if possible; returns 0 on success, error otherwise
status_t tryLock();
// Manages the mutex automatically. It'll be locked when Autolock is
// constructed and released when Autolock goes out of scope.
class Autolock {
public:
inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); }
inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); }
inline ~Autolock() { mLock.unlock(); }
private:
Mutex& mLock;
};
private:
friend class Condition;
// A mutex cannot be copied
Mutex(const Mutex&);
Mutex& operator = (const Mutex&);
#if defined(HAVE_PTHREADS)
pthread_mutex_t mMutex;
#else
void _init();
void* mState;
#endif
};
// ---------------------------------------------------------------------------
#if defined(HAVE_PTHREADS)
inline Mutex::Mutex() {
pthread_mutex_init(&mMutex, NULL);
}
inline Mutex::Mutex(__attribute__((unused)) const char* name) {
pthread_mutex_init(&mMutex, NULL);
}
inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
if (type == SHARED) {
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(&mMutex, &attr);
pthread_mutexattr_destroy(&attr);
} else {
pthread_mutex_init(&mMutex, NULL);
}
}
inline Mutex::~Mutex() {
pthread_mutex_destroy(&mMutex);
}
inline status_t Mutex::lock() {
return -pthread_mutex_lock(&mMutex);
}
inline void Mutex::unlock() {
pthread_mutex_unlock(&mMutex);
}
inline status_t Mutex::tryLock() {
return -pthread_mutex_trylock(&mMutex);
}
#endif // HAVE_PTHREADS
// ---------------------------------------------------------------------------
/*
* Automatic mutex. Declare one of these at the top of a function.
* When the function returns, it will go out of scope, and release the
* mutex.
*/
typedef Mutex::Autolock AutoMutex;
// ---------------------------------------------------------------------------
}; // namespace android
// ---------------------------------------------------------------------------
#endif // _LIBS_UTILS_MUTEX_H
#include "util.hpp"
extern "C" {
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
}
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <android/bitmap.h>
#include <utils/Mutex.h>
using namespace android;
#include <fpdfview.h>
#include <fpdf_doc.h>
#include <string>
static Mutex sLibraryLock;
static int sLibraryReferenceCount = 0;
static void initLibraryIfNeed(){
Mutex::Autolock lock(sLibraryLock);
if(sLibraryReferenceCount == 0){
LOGD("Init FPDF library");
FPDF_InitLibrary();
}
sLibraryReferenceCount++;
}
static void destroyLibraryIfNeed(){
Mutex::Autolock lock(sLibraryLock);
sLibraryReferenceCount--;
if(sLibraryReferenceCount == 0){
LOGD("Destroy FPDF library");
FPDF_DestroyLibrary();
}
}
struct rgb {
uint8_t red;
uint8_t green;
uint8_t blue;
};
class DocumentFile {
private:
int fileFd;
public:
FPDF_DOCUMENT pdfDocument = NULL;
size_t fileSize;
DocumentFile() { initLibraryIfNeed(); }
~DocumentFile();
};
DocumentFile::~DocumentFile(){
if(pdfDocument != NULL){
FPDF_CloseDocument(pdfDocument);
}
destroyLibraryIfNeed();
}
template <class string_type>
inline typename string_type::value_type* WriteInto(string_type* str, size_t length_with_null) {
str->reserve(length_with_null);
str->resize(length_with_null - 1);
return &((*str)[0]);
}
inline long getFileSize(int fd){
struct stat file_state;
if(fstat(fd, &file_state) >= 0){
return (long)(file_state.st_size);
}else{
LOGE("Error getting file size");
return 0;
}
}
static char* getErrorDescription(const long error) {
char* description = NULL;
switch(error) {
case FPDF_ERR_SUCCESS:
asprintf(&description, "No error.");
break;
case FPDF_ERR_FILE:
asprintf(&description, "File not found or could not be opened.");
break;
case FPDF_ERR_FORMAT:
asprintf(&description, "File not in PDF format or corrupted.");
break;
case FPDF_ERR_PASSWORD:
asprintf(&description, "Incorrect password.");
break;
case FPDF_ERR_SECURITY:
asprintf(&description, "Unsupported security scheme.");
break;
case FPDF_ERR_PAGE:
asprintf(&description, "Page not found or content error.");
break;
default:
asprintf(&description, "Unknown error.");
}
return description;
}
int jniThrowException(JNIEnv* env, const char* className, const char* message) {
jclass exClass = env->FindClass(className);
if (exClass == NULL) {
LOGE("Unable to find exception class %s", className);
return -1;
}
if(env->ThrowNew(exClass, message ) != JNI_OK) {
LOGE("Failed throwing '%s' '%s'", className, message);
return -1;
}
return 0;
}
int jniThrowExceptionFmt(JNIEnv* env, const char* className, const char* fmt, ...) {
va_list args;
va_start(args, fmt);
char msgBuf[512];
vsnprintf(msgBuf, sizeof(msgBuf), fmt, args);
return jniThrowException(env, className, msgBuf);
va_end(args);
}
jobject NewLong(JNIEnv* env, jlong value) {
jclass cls = env->FindClass("java/lang/Long");
jmethodID methodID = env->GetMethodID(cls, "<init>", "(J)V");
return env->NewObject(cls, methodID, value);
}
uint16_t rgbTo565(rgb *color) {
return ((color->red >> 3) << 11) | ((color->green >> 2) << 5) | (color->blue >> 3);
}
void rgbBitmapTo565(void *source, int sourceStride, void *dest, AndroidBitmapInfo *info) {
rgb *srcLine;
uint16_t *dstLine;
int y, x;
for (y = 0; y < info->height; y++) {
srcLine = (rgb*) source;
dstLine = (uint16_t*) dest;
for (x = 0; x < info->width; x++) {
dstLine[x] = rgbTo565(&srcLine[x]);
}
source = (char*) source + sourceStride;
dest = (char*) dest + info->stride;
}
}
extern "C" { //For JNI support
static int getBlock(void* param, unsigned long position, unsigned char* outBuffer,
unsigned long size) {
const int fd = reinterpret_cast<intptr_t>(param);
const int readCount = pread(fd, outBuffer, size, position);
if (readCount < 0) {
LOGE("Cannot read from file descriptor. Error:%d", errno);
return 0;
}
return 1;
}
JNI_FUNC(jlong, PdfiumCore, nativeOpenDocument)(JNI_ARGS, jint fd, jstring password){
size_t fileLength = (size_t)getFileSize(fd);
if(fileLength <= 0) {
jniThrowException(env, "java/io/IOException",
"File is empty");
return -1;
}
DocumentFile *docFile = new DocumentFile();
FPDF_FILEACCESS loader;
loader.m_FileLen = fileLength;
loader.m_Param = reinterpret_cast<void*>(intptr_t(fd));
loader.m_GetBlock = &getBlock;
const char *cpassword = NULL;
if(password != NULL) {
cpassword = env->GetStringUTFChars(password, NULL);
}
FPDF_DOCUMENT document = FPDF_LoadCustomDocument(&loader, cpassword);
if(cpassword != NULL) {
env->ReleaseStringUTFChars(password, cpassword);
}
if (!document) {
delete docFile;
const long errorNum = FPDF_GetLastError();
if(errorNum == FPDF_ERR_PASSWORD) {
jniThrowException(env, "com/shockwave/pdfium/PdfPasswordException",
"Password required or incorrect password.");
} else {
char* error = getErrorDescription(errorNum);
jniThrowExceptionFmt(env, "java/io/IOException",
"cannot create document: %s", error);
free(error);
}
return -1;
}
docFile->pdfDocument = document;
return reinterpret_cast<jlong>(docFile);
}
JNI_FUNC(jlong, PdfiumCore, nativeOpenMemDocument)(JNI_ARGS, jbyteArray data, jstring password){
DocumentFile *docFile = new DocumentFile();
const char *cpassword = NULL;
if(password != NULL) {
cpassword = env->GetStringUTFChars(password, NULL);
}
jbyte *cData = env->GetByteArrayElements(data, NULL);
int size = (int) env->GetArrayLength(data);
jbyte *cDataCopy = new jbyte[size];
memcpy(cDataCopy, cData, size);
FPDF_DOCUMENT document = FPDF_LoadMemDocument( reinterpret_cast<const void*>(cDataCopy),
size, cpassword);
env->ReleaseByteArrayElements(data, cData, JNI_ABORT);
if(cpassword != NULL) {
env->ReleaseStringUTFChars(password, cpassword);
}
if (!document) {
delete docFile;
const long errorNum = FPDF_GetLastError();
if(errorNum == FPDF_ERR_PASSWORD) {
jniThrowException(env, "com/shockwave/pdfium/PdfPasswordException",
"Password required or incorrect password.");
} else {
char* error = getErrorDescription(errorNum);
jniThrowExceptionFmt(env, "java/io/IOException",
"cannot create document: %s", error);
free(error);
}
return -1;
}
docFile->pdfDocument = document;
return reinterpret_cast<jlong>(docFile);
}
JNI_FUNC(jint, PdfiumCore, nativeGetPageCount)(JNI_ARGS, jlong documentPtr){
DocumentFile *doc = reinterpret_cast<DocumentFile*>(documentPtr);
return (jint)FPDF_GetPageCount(doc->pdfDocument);
}
JNI_FUNC(void, PdfiumCore, nativeCloseDocument)(JNI_ARGS, jlong documentPtr){
DocumentFile *doc = reinterpret_cast<DocumentFile*>(documentPtr);
delete doc;
}
static jlong loadPageInternal(JNIEnv *env, DocumentFile *doc, int pageIndex){
try{
if(doc == NULL) throw "Get page document null";
FPDF_DOCUMENT pdfDoc = doc->pdfDocument;
if(pdfDoc != NULL){
FPDF_PAGE page = FPDF_LoadPage(pdfDoc, pageIndex);
if (page == NULL) {
throw "Loaded page is null";
}
return reinterpret_cast<jlong>(page);
}else{
throw "Get page pdf document null";
}
}catch(const char *msg){
LOGE("%s", msg);
jniThrowException(env, "java/lang/IllegalStateException",
"cannot load page");
return -1;
}
}
static void closePageInternal(jlong pagePtr) { FPDF_ClosePage(reinterpret_cast<FPDF_PAGE>(pagePtr)); }
JNI_FUNC(jlong, PdfiumCore, nativeLoadPage)(JNI_ARGS, jlong docPtr, jint pageIndex){
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
return loadPageInternal(env, doc, (int)pageIndex);
}
JNI_FUNC(jlongArray, PdfiumCore, nativeLoadPages)(JNI_ARGS, jlong docPtr, jint fromIndex, jint toIndex){
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
if(toIndex < fromIndex) return NULL;
jlong pages[ toIndex - fromIndex + 1 ];
int i;
for(i = 0; i <= (toIndex - fromIndex); i++){
pages[i] = loadPageInternal(env, doc, (int)(i + fromIndex));
}
jlongArray javaPages = env -> NewLongArray( (jsize)(toIndex - fromIndex + 1) );
env -> SetLongArrayRegion(javaPages, 0, (jsize)(toIndex - fromIndex + 1), (const jlong*)pages);
return javaPages;
}
JNI_FUNC(void, PdfiumCore, nativeClosePage)(JNI_ARGS, jlong pagePtr){ closePageInternal(pagePtr); }
JNI_FUNC(void, PdfiumCore, nativeClosePages)(JNI_ARGS, jlongArray pagesPtr){
int length = (int)(env -> GetArrayLength(pagesPtr));
jlong *pages = env -> GetLongArrayElements(pagesPtr, NULL);
int i;
for(i = 0; i < length; i++){ closePageInternal(pages[i]); }
}
JNI_FUNC(jint, PdfiumCore, nativeGetPageWidthPixel)(JNI_ARGS, jlong pagePtr, jint dpi){
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
return (jint)(FPDF_GetPageWidth(page) * dpi / 72);
}
JNI_FUNC(jint, PdfiumCore, nativeGetPageHeightPixel)(JNI_ARGS, jlong pagePtr, jint dpi){
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
return (jint)(FPDF_GetPageHeight(page) * dpi / 72);
}
JNI_FUNC(jint, PdfiumCore, nativeGetPageWidthPoint)(JNI_ARGS, jlong pagePtr, jint dpi){
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
return (jint)FPDF_GetPageWidth(page);
}
JNI_FUNC(jint, PdfiumCore, nativeGetPageHeightPoint)(JNI_ARGS, jlong pagePtr, jint dpi){
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
return (jint)FPDF_GetPageHeight(page);
}
static void renderPageInternal( FPDF_PAGE page,
ANativeWindow_Buffer *windowBuffer,
int startX, int startY,
int canvasHorSize, int canvasVerSize,
int drawSizeHor, int drawSizeVer,
bool renderAnnot){
FPDF_BITMAP pdfBitmap = FPDFBitmap_CreateEx( canvasHorSize, canvasVerSize,
FPDFBitmap_BGRA,
windowBuffer->bits, (int)(windowBuffer->stride) * 4);
/*LOGD("Start X: %d", startX);
LOGD("Start Y: %d", startY);
LOGD("Canvas Hor: %d", canvasHorSize);
LOGD("Canvas Ver: %d", canvasVerSize);
LOGD("Draw Hor: %d", drawSizeHor);
LOGD("Draw Ver: %d", drawSizeVer);*/
if(drawSizeHor < canvasHorSize || drawSizeVer < canvasVerSize){
FPDFBitmap_FillRect( pdfBitmap, 0, 0, canvasHorSize, canvasVerSize,
0x848484FF); //Gray
}
int baseHorSize = (canvasHorSize < drawSizeHor)? canvasHorSize : drawSizeHor;
int baseVerSize = (canvasVerSize < drawSizeVer)? canvasVerSize : drawSizeVer;
int baseX = (startX < 0)? 0 : startX;
int baseY = (startY < 0)? 0 : startY;
int flags = FPDF_REVERSE_BYTE_ORDER;
if(renderAnnot) {
flags |= FPDF_ANNOT;
}
FPDFBitmap_FillRect( pdfBitmap, baseX, baseY, baseHorSize, baseVerSize,
0xFFFFFFFF); //White
FPDF_RenderPageBitmap( pdfBitmap, page,
startX, startY,
drawSizeHor, drawSizeVer,
0, flags );
}
JNI_FUNC(void, PdfiumCore, nativeRenderPage)(JNI_ARGS, jlong pagePtr, jobject objSurface,
jint dpi, jint startX, jint startY,
jint drawSizeHor, jint drawSizeVer,
jboolean renderAnnot){
ANativeWindow *nativeWindow = ANativeWindow_fromSurface(env, objSurface);
if(nativeWindow == NULL){
LOGE("native window pointer null");
return;
}
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
if(page == NULL || nativeWindow == NULL){
LOGE("Render page pointers invalid");
return;
}
if(ANativeWindow_getFormat(nativeWindow) != WINDOW_FORMAT_RGBA_8888){
LOGD("Set format to RGBA_8888");
ANativeWindow_setBuffersGeometry( nativeWindow,
ANativeWindow_getWidth(nativeWindow),
ANativeWindow_getHeight(nativeWindow),
WINDOW_FORMAT_RGBA_8888 );
}
ANativeWindow_Buffer buffer;
int ret;
if( (ret = ANativeWindow_lock(nativeWindow, &buffer, NULL)) != 0 ){
LOGE("Locking native window failed: %s", strerror(ret * -1));
return;
}
renderPageInternal(page, &buffer,
(int)startX, (int)startY,
buffer.width, buffer.height,
(int)drawSizeHor, (int)drawSizeVer,
(bool)renderAnnot);
ANativeWindow_unlockAndPost(nativeWindow);
ANativeWindow_release(nativeWindow);
}
JNI_FUNC(void, PdfiumCore, nativeRenderPageBitmap)(JNI_ARGS, jlong pagePtr, jobject bitmap,
jint dpi, jint startX, jint startY,
jint drawSizeHor, jint drawSizeVer,
jboolean renderAnnot){
FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
if(page == NULL || bitmap == NULL){
LOGE("Render page pointers invalid");
return;
}
AndroidBitmapInfo info;
int ret;
if((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
LOGE("Fetching bitmap info failed: %s", strerror(ret * -1));
return;
}
int canvasHorSize = info.width;
int canvasVerSize = info.height;
if(info.format != ANDROID_BITMAP_FORMAT_RGBA_8888 && info.format != ANDROID_BITMAP_FORMAT_RGB_565){
LOGE("Bitmap format must be RGBA_8888 or RGB_565");
return;
}
void *addr;
if( (ret = AndroidBitmap_lockPixels(env, bitmap, &addr)) != 0 ){
LOGE("Locking bitmap failed: %s", strerror(ret * -1));
return;
}
void *tmp;
int format;
int sourceStride;
if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
tmp = malloc(canvasVerSize * canvasHorSize * sizeof(rgb));
sourceStride = canvasHorSize * sizeof(rgb);
format = FPDFBitmap_BGR;
} else {
tmp = addr;
sourceStride = info.stride;
format = FPDFBitmap_BGRA;
}
FPDF_BITMAP pdfBitmap = FPDFBitmap_CreateEx( canvasHorSize, canvasVerSize,
format, tmp, sourceStride);
/*LOGD("Start X: %d", startX);
LOGD("Start Y: %d", startY);
LOGD("Canvas Hor: %d", canvasHorSize);
LOGD("Canvas Ver: %d", canvasVerSize);
LOGD("Draw Hor: %d", drawSizeHor);
LOGD("Draw Ver: %d", drawSizeVer);*/
if(drawSizeHor < canvasHorSize || drawSizeVer < canvasVerSize){
FPDFBitmap_FillRect( pdfBitmap, 0, 0, canvasHorSize, canvasVerSize,
0x848484FF); //Gray
}
int baseHorSize = (canvasHorSize < drawSizeHor)? canvasHorSize : (int)drawSizeHor;
int baseVerSize = (canvasVerSize < drawSizeVer)? canvasVerSize : (int)drawSizeVer;
int baseX = (startX < 0)? 0 : (int)startX;
int baseY = (startY < 0)? 0 : (int)startY;
int flags = FPDF_REVERSE_BYTE_ORDER;
if(renderAnnot) {
flags |= FPDF_ANNOT;
}
FPDFBitmap_FillRect( pdfBitmap, baseX, baseY, baseHorSize, baseVerSize,
0xFFFFFFFF); //White
FPDF_RenderPageBitmap( pdfBitmap, page,
startX, startY,
(int)drawSizeHor, (int)drawSizeVer,
0, flags );
if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) {
rgbBitmapTo565(tmp, sourceStride, addr, &info);
free(tmp);
}
AndroidBitmap_unlockPixels(env, bitmap);
}
JNI_FUNC(jstring, PdfiumCore, nativeGetDocumentMetaText)(JNI_ARGS, jlong docPtr, jstring tag) {
const char *ctag = env->GetStringUTFChars(tag, NULL);
if (ctag == NULL) {
return env->NewStringUTF("");
}
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
size_t buffer_bytes = FPDF_GetMetaText(doc->pdfDocument, ctag, NULL, 0);
if (buffer_bytes <= 2) {
return env->NewStringUTF("");
}
std::wstring text;
FPDF_GetMetaText(doc->pdfDocument, ctag, WriteInto(&text, buffer_bytes + 1), buffer_bytes);
env->ReleaseStringUTFChars(tag, ctag);
return env->NewString((jchar*) text.c_str(), buffer_bytes / 2 - 1);
}
JNI_FUNC(jobject, PdfiumCore, nativeGetFirstChildBookmark)(JNI_ARGS, jlong docPtr, jobject bookmarkPtr) {
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
FPDF_BOOKMARK parent;
if(bookmarkPtr == NULL) {
parent = NULL;
} else {
jclass longClass = env->GetObjectClass(bookmarkPtr);
jmethodID longValueMethod = env->GetMethodID(longClass, "longValue", "()J");
jlong ptr = env->CallLongMethod(bookmarkPtr, longValueMethod);
parent = reinterpret_cast<FPDF_BOOKMARK>(ptr);
}
FPDF_BOOKMARK bookmark = FPDFBookmark_GetFirstChild(doc->pdfDocument, parent);
if (bookmark == NULL) {
return NULL;
}
return NewLong(env, reinterpret_cast<jlong>(bookmark));
}
JNI_FUNC(jobject, PdfiumCore, nativeGetSiblingBookmark)(JNI_ARGS, jlong docPtr, jlong bookmarkPtr) {
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
FPDF_BOOKMARK parent = reinterpret_cast<FPDF_BOOKMARK>(bookmarkPtr);
FPDF_BOOKMARK bookmark = FPDFBookmark_GetNextSibling(doc->pdfDocument, parent);
if (bookmark == NULL) {
return NULL;
}
return NewLong(env, reinterpret_cast<jlong>(bookmark));
}
JNI_FUNC(jstring, PdfiumCore, nativeGetBookmarkTitle)(JNI_ARGS, jlong bookmarkPtr) {
FPDF_BOOKMARK bookmark = reinterpret_cast<FPDF_BOOKMARK>(bookmarkPtr);
size_t buffer_bytes = FPDFBookmark_GetTitle(bookmark, NULL, 0);
if (buffer_bytes <= 2) {
return env->NewStringUTF("");
}
std::wstring title;
FPDFBookmark_GetTitle(bookmark, WriteInto(&title, buffer_bytes + 1), buffer_bytes);
return env->NewString((jchar*) title.c_str(), buffer_bytes / 2 - 1);
}
JNI_FUNC(jlong, PdfiumCore, nativeGetBookmarkDestIndex)(JNI_ARGS, jlong docPtr, jlong bookmarkPtr) {
DocumentFile *doc = reinterpret_cast<DocumentFile*>(docPtr);
FPDF_BOOKMARK bookmark = reinterpret_cast<FPDF_BOOKMARK>(bookmarkPtr);
FPDF_DEST dest = FPDFBookmark_GetDest(doc->pdfDocument, bookmark);
if (dest == NULL) {
return -1;
}
return (jlong) FPDFDest_GetPageIndex(doc->pdfDocument, dest);
}
}//extern C
#ifndef _UTIL_HPP_
#define _UTIL_HPP_
#include <jni.h>
extern "C" {
#include <stdlib.h>
}
#include <android/log.h>
#define JNI_FUNC(retType, bindClass, name) JNIEXPORT retType JNICALL Java_com_shockwave_pdfium_##bindClass##_##name
#define JNI_ARGS JNIEnv *env, jobject thiz
#define LOG_TAG "jniPdfium"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#endif
extern "C"
JNIEXPORT jlong JNICALL
Java_com_shockwave_pdfium_PdfiumCore_TestJniFun(JNIEnv *env, jobject thiz) {
long longValue = 179621228;
return longValue;
}
\ No newline at end of file
package com.shockwave.pdfium;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
\ No newline at end of file
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
ext {
// bintrayRepo = 'maven'
// bintrayName = 'android-pdf-viewer'
// publishedGroupId = 'com.github.barteksc'
// libraryName = 'AndroidPdfViewer'
// artifact = 'android-pdf-viewer'
// libraryDescription = 'Android view for displaying PDFs rendered with PdfiumAndroid'
// siteUrl = 'https://github.com/barteksc/AndroidPdfViewer'
// gitUrl = 'https://github.com/barteksc/AndroidPdfViewer.git'
// libraryVersion = '2.8.1'
// developerId = 'barteksc'
// developerName = 'Bartosz Schiller'
// developerEmail = 'barteksch@boo.pl'
// licenseName = 'The Apache Software License, Version 2.0'
// licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
// allLicenses = ["Apache-2.0"]
}
android {
compileSdk = 34
namespace = "com.github.barteksc.pdfviewer"
defaultConfig {
minSdkVersion 24
targetSdkVersion 34
versionCode 1
versionName "2.8.1"
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
// api 'com.github.barteksc:pdfium-android:1.7.1'
api project(':PdfiumAndroid')
implementation("androidx.appcompat:appcompat:1.7.0")
implementation "androidx.core:core-ktx:$kotlin_version"
}
//apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/installv1.gradle'
//apply from: 'https://raw.githubusercontent.com/nuuneoi/JCenter/master/bintrayv1.gradle'
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.barteksc.pdfviewer">
</manifest>
\ No newline at end of file
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.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;
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);
animation.setInterpolator(new DecelerateInterpolator());
animation.addUpdateListener(new XAnimation());
animation.setDuration(400);
animation.start();
}
public void startYAnimation(float yFrom, float yTo) {
stopAll();
animation = ValueAnimator.ofFloat(yFrom, yTo);
animation.setInterpolator(new DecelerateInterpolator());
animation.addUpdateListener(new 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);
}
void computeFling() {
if (scroller.computeScrollOffset()) {
pdfView.moveTo(scroller.getCurrX(), scroller.getCurrY());
pdfView.loadPageByOffset();
} else if(flinging) { // fling finished
flinging = false;
pdfView.loadPages();
hideHandle();
}
}
public void stopAll() {
if (animation != null) {
animation.cancel();
animation = null;
}
stopFling();
}
public void stopFling() {
flinging = false;
scroller.forceFinished(true);
}
class XAnimation implements AnimatorUpdateListener {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float offset = (Float) animation.getAnimatedValue();
pdfView.moveTo(offset, pdfView.getCurrentYOffset());
}
}
class YAnimation implements AnimatorUpdateListener {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float offset = (Float) animation.getAnimatedValue();
pdfView.moveTo(pdfView.getCurrentXOffset(), offset);
}
}
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) {
}
@Override
public void onAnimationEnd(Animator animation) {
pdfView.loadPages();
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
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 com.github.barteksc.pdfviewer.model.PagePart;
import java.util.ArrayList;
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;
import org.jetbrains.annotations.Nullable;
class CacheManager {
private final PriorityQueue<PagePart> passiveCache;
private final PriorityQueue<PagePart> activeCache;
private final List<PagePart> thumbnails;
private final Object passiveActiveLock = new Object();
private final PagePartComparator comparator = new PagePartComparator();
public CacheManager() {
activeCache = new PriorityQueue<>(CACHE_SIZE, comparator);
passiveCache = new PriorityQueue<>(CACHE_SIZE, comparator);
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
if (thumbnails.size() >= THUMBNAILS_CACHE_SIZE) {
thumbnails.remove(0).getRenderedBitmap().recycle();
}
// Then add thumbnail
thumbnails.add(part);
}
}
public boolean upPartIfContained(int userPage, int page, float width, float height, RectF pageRelativeBounds, int toOrder) {
PagePart fakePart = new PagePart(userPage, page, null, width, height, 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 userPage, int page, float width, float height, RectF pageRelativeBounds) {
PagePart fakePart = new PagePart(userPage, page, null, width, height, pageRelativeBounds, true, 0);
synchronized (thumbnails) {
for (PagePart part : thumbnails) {
if (part.equals(fakePart)) {
return true;
}
}
return false;
}
}
@Nullable
private static PagePart find(PriorityQueue<PagePart> vector, PagePart fakePart) {
for (PagePart part : vector) {
if (part.equals(fakePart)) {
return part;
}
}
return null;
}
public List<PagePart> getPageParts() {
synchronized (passiveActiveLock) {
List<PagePart> parts = new ArrayList<>(passiveCache);
parts.addAll(activeCache);
return parts;
}
}
public List<PagePart> 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<PagePart> {
@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
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.os.AsyncTask;
import com.github.barteksc.pdfviewer.source.DocumentSource;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
class DecodingAsyncTask extends AsyncTask<Void, Void, Throwable> {
private boolean cancelled;
private PDFView pdfView;
private Context context;
private PdfiumCore pdfiumCore;
private PdfDocument pdfDocument;
private String password;
private DocumentSource docSource;
private int firstPageIdx;
private int pageWidth;
private int pageHeight;
DecodingAsyncTask(DocumentSource docSource, String password, PDFView pdfView, PdfiumCore pdfiumCore, int firstPageIdx) {
this.docSource = docSource;
this.firstPageIdx = firstPageIdx;
this.cancelled = false;
this.pdfView = pdfView;
this.password = password;
this.pdfiumCore = pdfiumCore;
context = pdfView.getContext();
}
@Override
protected Throwable doInBackground(Void... params) {
try {
pdfDocument = docSource.createDocument(context, pdfiumCore, password);
// We assume all the pages are the same size
pdfiumCore.openPage(pdfDocument, firstPageIdx);
pageWidth = pdfiumCore.getPageWidth(pdfDocument, firstPageIdx);
pageHeight = pdfiumCore.getPageHeight(pdfDocument, firstPageIdx);
return null;
} catch (Throwable t) {
return t;
}
}
@Override
protected void onPostExecute(Throwable t) {
if (t != null) {
pdfView.loadError(t);
return;
}
if (!cancelled) {
pdfView.loadComplete(pdfDocument, pageWidth, pageHeight);
}
}
@Override
protected void onCancelled() {
cancelled = true;
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import com.github.barteksc.pdfviewer.scroll.ScrollHandle;
import com.github.barteksc.pdfviewer.listener.OnTapListener;
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 isSwipeEnabled;
private boolean swipeVertical;
private boolean scrolling = false;
private boolean scaling = false;
public DragPinchManager(PDFView pdfView, AnimationManager animationManager) {
this.pdfView = pdfView;
this.animationManager = animationManager;
this.isSwipeEnabled = false;
this.swipeVertical = pdfView.isSwipeVertical();
gestureDetector = new GestureDetector(pdfView.getContext(), this);
scaleGestureDetector = new ScaleGestureDetector(pdfView.getContext(), this);
pdfView.setOnTouchListener(this);
}
public void enableDoubletap(boolean enableDoubletap) {
if (enableDoubletap) {
gestureDetector.setOnDoubleTapListener(this);
} else {
gestureDetector.setOnDoubleTapListener(null);
}
}
public boolean isZooming() {
return pdfView.isZooming();
}
private boolean isPageChange(float distance) {
return Math.abs(distance) > Math.abs(pdfView.toCurrentScale(swipeVertical ? pdfView.getOptimalPageHeight() : pdfView.getOptimalPageWidth()) / 2);
}
public void setSwipeEnabled(boolean isSwipeEnabled) {
this.isSwipeEnabled = isSwipeEnabled;
}
public void setSwipeVertical(boolean swipeVertical) {
this.swipeVertical = swipeVertical;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
OnTapListener onTapListener = pdfView.getOnTapListener();
if (onTapListener == null || !onTapListener.onTap(e)) {
ScrollHandle ps = pdfView.getScrollHandle();
if (ps != null && !pdfView.documentFitsView()) {
if (!ps.shown()) {
ps.show();
} else {
ps.hide();
}
}
}
pdfView.performClick();
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
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 (isZooming() || isSwipeEnabled) {
pdfView.moveRelativeTo(-distanceX, -distanceY);
}
if (!scaling || pdfView.doRenderDuringScale()) {
pdfView.loadPageByOffset();
}
return true;
}
public void onScrollEnd(MotionEvent event) {
pdfView.loadPages();
hideHandle();
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int xOffset = (int) pdfView.getCurrentXOffset();
int yOffset = (int) pdfView.getCurrentYOffset();
float minX, minY;
if (pdfView.isSwipeVertical()) {
minX = -(pdfView.toCurrentScale(pdfView.getOptimalPageWidth()) - pdfView.getWidth());
minY = -(pdfView.calculateDocLength() - pdfView.getHeight());
} else {
minX = -(pdfView.calculateDocLength() - pdfView.getWidth());
minY = -(pdfView.toCurrentScale(pdfView.getOptimalPageHeight()) - pdfView.getHeight());
}
animationManager.startFlingAnimation(xOffset, yOffset, (int) (velocityX), (int) (velocityY),
(int) minX, 0, (int) minY, 0);
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float dr = detector.getScaleFactor();
float wantedZoom = pdfView.getZoom() * dr;
if (wantedZoom < MINIMUM_ZOOM) {
dr = MINIMUM_ZOOM / pdfView.getZoom();
} else if (wantedZoom > MAXIMUM_ZOOM) {
dr = MAXIMUM_ZOOM / 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) {
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() {
if (pdfView.getScrollHandle() != null && pdfView.getScrollHandle().shown()) {
pdfView.getScrollHandle().hideDelayed();
}
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.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.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.listener.OnDrawListener;
import com.github.barteksc.pdfviewer.listener.OnErrorListener;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
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.ArrayUtils;
import com.github.barteksc.pdfviewer.util.Constants;
import com.github.barteksc.pdfviewer.util.MathUtils;
import com.github.barteksc.pdfviewer.util.Util;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* It supports animations, zoom, cache, and swipe.
* <p>
* 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
* <p>
* 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, OnLoadCompleteListener, OnErrorListener, 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;
/**
* The pages the user want to display in order
* (ex: 0, 2, 2, 8, 8, 1, 1, 1)
*/
private int[] originalUserPages;
/**
* The same pages but with a filter to avoid repetition
* (ex: 0, 2, 8, 1)
*/
private int[] filteredUserPages;
/**
* The same pages but with a filter to avoid repetition
* (ex: 0, 1, 1, 2, 2, 3, 3, 3)
*/
private int[] filteredUserPageIndexes;
/**
* Number of pages in the loaded PDF document
*/
private int documentPageCount;
/**
* The index of the current sequence
*/
private int currentPage;
/**
* The index of the current sequence
*/
private int currentFilteredPage;
/**
* The actual width and height of the pages in the PDF document
*/
private int pageWidth, pageHeight;
/**
* The optimal width and height of the pages to fit the component size
*/
private float optimalPageWidth, optimalPageHeight;
/**
* 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 final HandlerThread renderingHandlerThread;
/**
* Handler always waiting in the background and rendering tasks
*/
RenderingHandler renderingHandler;
private PagesLoader pagesLoader;
/**
* Call back object to call when the PDF is loaded
*/
private OnLoadCompleteListener onLoadCompleteListener;
private OnErrorListener onErrorListener;
/**
* Call back object to call when the page has changed
*/
private OnPageChangeListener onPageChangeListener;
/**
* Call back object to call when the page is scrolled
*/
private OnPageScrollListener onPageScrollListener;
/**
* Call back object to call when the above layer is to drawn
*/
private OnDrawListener onDrawListener;
private OnDrawListener onDrawAllListener;
/**
* Call back object to call when the document is initially rendered
*/
private OnRenderListener onRenderListener;
/**
* Call back object to call when the user does a tap gesture
*/
private OnTapListener onTapListener;
/**
* Call back object to call when the page load error occurs
*/
private OnPageErrorListener onPageErrorListener;
/**
* Paint object for drawing
*/
private Paint paint;
/**
* Paint object for drawing debug stuff
*/
private Paint debugPaint;
/**
* Paint used for invalid pages
*/
private int invalidPageColor = Color.WHITE;
private int defaultPage = 0;
/**
* True if should scroll through pages vertically instead of horizontally
*/
private boolean swipeVertical = true;
/**
* Pdfium core for loading and rendering PDFs
*/
private PdfiumCore pdfiumCore;
private PdfDocument pdfDocument;
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<br/>
* Can not be forced on older API versions (< Build.VERSION_CODES.KITKAT) as the GestureDetector does
* not detect scrolling while scaling.<br/>
* 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 DP
*/
private int spacingPx = 0;
/**
* pages numbers used when calling onDrawAllListener
*/
private List<Integer> onDrawPagesNums = new ArrayList<>(10);
/**
* 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);
paint = new Paint();
debugPaint = new Paint();
debugPaint.setStyle(Style.STROKE);
pdfiumCore = new PdfiumCore(context);
setWillNotDraw(false);
}
private void load(DocumentSource docSource, String password, OnLoadCompleteListener listener, OnErrorListener onErrorListener) {
load(docSource, password, listener, onErrorListener, null);
}
private void load(DocumentSource docSource, String password, OnLoadCompleteListener onLoadCompleteListener, OnErrorListener onErrorListener, int[] userPages) {
if (!recycled) {
throw new IllegalStateException("Don't call load on a PDF View without recycling it first.");
}
// Manage UserPages if not null
if (userPages != null) {
this.originalUserPages = userPages;
this.filteredUserPages = ArrayUtils.deleteDuplicatedPages(originalUserPages);
this.filteredUserPageIndexes = ArrayUtils.calculateIndexesInDuplicateArray(originalUserPages);
}
this.onLoadCompleteListener = onLoadCompleteListener;
this.onErrorListener = onErrorListener;
int firstPageIdx = 0;
if (originalUserPages != null) {
firstPageIdx = originalUserPages[0];
}
recycled = false;
// Start decoding document
decodingAsyncTask = new DecodingAsyncTask(docSource, password, this, pdfiumCore, firstPageIdx);
decodingAsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
/**
* Go to the given page.
*
* @param page Page index.
*/
public void jumpTo(int page, boolean withAnimation) {
float offset = -calculatePageOffset(page);
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 = determineValidPageNumberFrom(pageNb);
currentPage = pageNb;
currentFilteredPage = pageNb;
if (filteredUserPageIndexes != null) {
if (pageNb >= 0 && pageNb < filteredUserPageIndexes.length) {
pageNb = filteredUserPageIndexes[pageNb];
currentFilteredPage = pageNb;
}
}
loadPages();
if (scrollHandle != null && !documentFitsView()) {
scrollHandle.setPageNum(currentPage + 1);
}
if (onPageChangeListener != null) {
onPageChangeListener.onPageChanged(currentPage, getPageCount());
}
}
/**
* 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 / (calculateDocLength() - getHeight());
} else {
offset = -currentXOffset / (calculateDocLength() - 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, (-calculateDocLength() + getHeight()) * progress, moveHandle);
} else {
moveTo((-calculateDocLength() + getWidth()) * progress, currentYOffset, moveHandle);
}
loadPageByOffset();
}
public void setPositionOffset(float progress) {
setPositionOffset(progress, true);
}
private float calculatePageOffset(int page) {
if (swipeVertical) {
return toCurrentScale(page * optimalPageHeight + page * spacingPx);
} else {
return toCurrentScale(page * optimalPageWidth + page * spacingPx);
}
}
float calculateDocLength() {
int pageCount = getPageCount();
if (swipeVertical) {
return toCurrentScale(pageCount * optimalPageHeight + (pageCount - 1) * spacingPx);
} else {
return toCurrentScale(pageCount * optimalPageWidth + (pageCount - 1) * spacingPx);
}
}
public void stopFling() {
animationManager.stopFling();
}
public int getPageCount() {
if (originalUserPages != null) {
return originalUserPages.length;
}
return documentPageCount;
}
public void enableSwipe(boolean enableSwipe) {
dragPinchManager.setSwipeEnabled(enableSwipe);
}
public void enableDoubletap(boolean enableDoubletap) {
this.dragPinchManager.enableDoubletap(enableDoubletap);
}
private void setOnPageChangeListener(OnPageChangeListener onPageChangeListener) {
this.onPageChangeListener = onPageChangeListener;
}
OnPageChangeListener getOnPageChangeListener() {
return this.onPageChangeListener;
}
private void setOnPageScrollListener(OnPageScrollListener onPageScrollListener) {
this.onPageScrollListener = onPageScrollListener;
}
OnPageScrollListener getOnPageScrollListener() {
return this.onPageScrollListener;
}
private void setOnRenderListener(OnRenderListener onRenderListener) {
this.onRenderListener = onRenderListener;
}
OnRenderListener getOnRenderListener() {
return this.onRenderListener;
}
private void setOnTapListener(OnTapListener onTapListener) {
this.onTapListener = onTapListener;
}
OnTapListener getOnTapListener() {
return this.onTapListener;
}
private void setOnDrawListener(OnDrawListener onDrawListener) {
this.onDrawListener = onDrawListener;
}
private void setOnDrawAllListener(OnDrawListener onDrawAllListener) {
this.onDrawAllListener = onDrawAllListener;
}
private void setOnPageErrorListener(OnPageErrorListener onPageErrorListener) {
this.onPageErrorListener = onPageErrorListener;
}
void onPageError(PageRenderingException ex) {
if (onPageErrorListener != null) {
onPageErrorListener.onPageError(ex.getPage(), ex.getCause());
} else {
Log.e(TAG, "Cannot open page " + ex.getPage(), ex.getCause());
}
}
public void recycle() {
animationManager.stopAll();
// 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 (pdfiumCore != null && pdfDocument != null) {
pdfiumCore.closeDocument(pdfDocument);
}
renderingHandler = null;
originalUserPages = null;
filteredUserPages = null;
filteredUserPageIndexes = null;
pdfDocument = null;
scrollHandle = null;
isScrollHandleInit = false;
currentXOffset = currentYOffset = 0;
zoom = 1f;
recycled = true;
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();
super.onDetachedFromWindow();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (isInEditMode() || state != State.SHOWN) {
return;
}
animationManager.stopAll();
calculateOptimalWidthAndHeight();
if (swipeVertical) {
moveTo(currentXOffset, -calculatePageOffset(currentPage));
} else {
moveTo(-calculatePageOffset(currentPage), currentYOffset);
}
loadPageByOffset();
}
@Override
public boolean canScrollHorizontally(int direction) {
if (swipeVertical) {
if (direction < 0 && currentXOffset < 0) {
return true;
} else if (direction > 0 && currentXOffset + toCurrentScale(optimalPageWidth) > getWidth()) {
return true;
}
} else {
if (direction < 0 && currentXOffset < 0) {
return true;
} else if (direction > 0 && currentXOffset + calculateDocLength() > getWidth()) {
return true;
}
}
return false;
}
@Override
public boolean canScrollVertically(int direction) {
if (swipeVertical) {
if (direction < 0 && currentYOffset < 0) {
return true;
} else if (direction > 0 && currentYOffset + calculateDocLength() > getHeight()) {
return true;
}
} else {
if (direction < 0 && currentYOffset < 0) {
return true;
} else if (direction > 0 && currentYOffset + toCurrentScale(optimalPageHeight) > 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(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 (onDrawAllListener != null && !onDrawPagesNums.contains(part.getUserPage())) {
onDrawPagesNums.add(part.getUserPage());
}
}
for (Integer page : onDrawPagesNums) {
drawWithListener(canvas, page, onDrawAllListener);
}
onDrawPagesNums.clear();
drawWithListener(canvas, currentPage, onDrawListener);
// 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 = calculatePageOffset(page);
} else {
translateY = 0;
translateX = calculatePageOffset(page);
}
canvas.translate(translateX, translateY);
listener.onLayerDrawn(canvas,
toCurrentScale(optimalPageWidth),
toCurrentScale(optimalPageHeight),
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;
if (swipeVertical) {
localTranslationY = calculatePageOffset(part.getUserPage());
} else {
localTranslationX = calculatePageOffset(part.getUserPage());
}
canvas.translate(localTranslationX, localTranslationY);
Rect srcRect = new Rect(0, 0, renderedBitmap.getWidth(),
renderedBitmap.getHeight());
float offsetX = toCurrentScale(pageRelativeBounds.left * optimalPageWidth);
float offsetY = toCurrentScale(pageRelativeBounds.top * optimalPageHeight);
float width = toCurrentScale(pageRelativeBounds.width() * optimalPageWidth);
float height = toCurrentScale(pageRelativeBounds.height() * optimalPageHeight);
// 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.getUserPage() % 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 (optimalPageWidth == 0 || optimalPageHeight == 0 || 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(PdfDocument pdfDocument, int pageWidth, int pageHeight) {
state = State.LOADED;
this.documentPageCount = pdfiumCore.getPageCount(pdfDocument);
this.pdfDocument = pdfDocument;
this.pageWidth = pageWidth;
this.pageHeight = pageHeight;
calculateOptimalWidthAndHeight();
pagesLoader = new PagesLoader(this);
if (!renderingHandlerThread.isAlive()) {
renderingHandlerThread.start();
}
renderingHandler = new RenderingHandler(renderingHandlerThread.getLooper(),
this, pdfiumCore, pdfDocument);
renderingHandler.start();
if (scrollHandle != null) {
scrollHandle.setupLayout(this);
isScrollHandleInit = true;
}
if (onLoadCompleteListener != null) {
onLoadCompleteListener.loadComplete(documentPageCount);
}
jumpTo(defaultPage, false);
}
void loadError(Throwable t) {
state = State.ERROR;
recycle();
invalidate();
if (this.onErrorListener != null) {
this.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;
if (onRenderListener != null) {
onRenderListener.onInitiallyRendered(getPageCount(), optimalPageWidth, optimalPageHeight);
}
}
if (part.isThumbnail()) {
cacheManager.cacheThumbnail(part);
} else {
cacheManager.cachePart(part);
}
redraw();
}
/**
* Given the UserPage number, this method restrict it
* to be sure it's an existing page. It takes care of
* using the user defined pages if any.
*
* @param userPage A page number.
* @return A restricted valid page number (example : -2 => 0)
*/
private int determineValidPageNumberFrom(int userPage) {
if (userPage <= 0) {
return 0;
}
if (originalUserPages != null) {
if (userPage >= originalUserPages.length) {
return originalUserPages.length - 1;
}
} else {
if (userPage >= documentPageCount) {
return documentPageCount - 1;
}
}
return userPage;
}
/**
* Calculate the x/y-offset needed to have the given
* page centered on the screen. It doesn't take into
* account the zoom level.
*
* @param pageNb The page number.
* @return The x/y-offset to use to have the pageNb centered.
*/
private float calculateCenterOffsetForPage(int pageNb) {
if (swipeVertical) {
float imageY = -(pageNb * optimalPageHeight + pageNb * spacingPx);
imageY += getHeight() / 2 - optimalPageHeight / 2;
return imageY;
} else {
float imageX = -(pageNb * optimalPageWidth + pageNb * spacingPx);
imageX += getWidth() / 2 - optimalPageWidth / 2;
return imageX;
}
}
/**
* Calculate the optimal width and height of a page
* considering the area width and height
*/
private void calculateOptimalWidthAndHeight() {
if (state == State.DEFAULT || getWidth() == 0) {
return;
}
float maxWidth = getWidth(), maxHeight = getHeight();
float w = pageWidth, h = pageHeight;
float ratio = w / h;
w = maxWidth;
h = (float) Math.floor(maxWidth / ratio);
if (h > maxHeight) {
h = maxHeight;
w = (float) Math.floor(maxHeight * ratio);
}
optimalPageWidth = w;
optimalPageHeight = h;
}
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(optimalPageWidth);
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 = calculateDocLength();
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(optimalPageHeight);
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 = calculateDocLength();
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);
}
if (onPageScrollListener != null) {
onPageScrollListener.onPageScrolled(getCurrentPage(), positionOffset);
}
redraw();
}
ScrollDir getScrollDir() {
return scrollDir;
}
void loadPageByOffset() {
if (0 == getPageCount()) {
return;
}
float offset, optimal, screenCenter;
float spacingPerPage = spacingPx - (spacingPx / getPageCount());
if (swipeVertical) {
offset = currentYOffset;
optimal = optimalPageHeight + spacingPerPage;
screenCenter = ((float) getHeight()) / 2;
} else {
offset = currentXOffset;
optimal = optimalPageWidth + spacingPerPage;
screenCenter = ((float) getWidth()) / 2;
}
int page = (int) Math.floor((Math.abs(offset) + screenCenter) / toCurrentScale(optimal));
if (page >= 0 && page <= getPageCount() - 1 && page != getCurrentPage()) {
showPage(page);
} else {
loadPages();
}
}
int[] getFilteredUserPages() {
return filteredUserPages;
}
int[] getOriginalUserPages() {
return originalUserPages;
}
int[] getFilteredUserPageIndexes() {
return filteredUserPageIndexes;
}
int getDocumentPageCount() {
return documentPageCount;
}
/**
* 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() {
int pageCount = getPageCount();
int spacing = (pageCount - 1) * spacingPx;
if (swipeVertical) {
return pageCount * optimalPageHeight + spacing < getHeight();
} else {
return pageCount * optimalPageWidth + spacing < getWidth();
}
}
public void fitToWidth(int page) {
if (state != State.SHOWN) {
Log.e(TAG, "Cannot fit, document not rendered yet");
return;
}
fitToWidth();
jumpTo(page);
}
public void fitToWidth() {
if (state != State.SHOWN) {
Log.e(TAG, "Cannot fit, document not rendered yet");
return;
}
zoomTo(getWidth() / optimalPageWidth);
setPositionOffset(0);
}
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;
}
public float getOptimalPageWidth() {
return optimalPageWidth;
}
public float getOptimalPageHeight() {
return optimalPageHeight;
}
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) {
int page = (int) Math.floor(getPageCount() * positionOffset);
return page == getPageCount() ? page - 1 : page;
}
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 isSwipeVertical() {
return swipeVertical;
}
public 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;
}
int getSpacingPx() {
return spacingPx;
}
private void setSpacing(int spacing) {
this.spacingPx = Util.getDP(getContext(), spacing);
}
private void setInvalidPageColor(int invalidPageColor) {
this.invalidPageColor = invalidPageColor;
}
public int getInvalidPageColor() {
return invalidPageColor;
}
public boolean doRenderDuringScale() {
return renderDuringScale;
}
public PdfDocument.Meta getDocumentMeta() {
if (pdfDocument == null) {
return null;
}
return pdfiumCore.getDocumentMeta(pdfDocument);
}
public List<PdfDocument.Bookmark> getTableOfContents() {
if (pdfDocument == null) {
return new ArrayList<>();
}
return pdfiumCore.getTableOfContents(pdfDocument);
}
/**
* 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
*
* @param bytes
* @return
*/
public Configurator fromBytes(byte[] bytes) {
return new Configurator(new ByteArraySource(bytes));
}
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 OnPageErrorListener onPageErrorListener;
private int defaultPage = 0;
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 int invalidPageColor = Color.WHITE;
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 defaultPage(int defaultPage) {
this.defaultPage = defaultPage;
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 invalidPageColor(int invalidPageColor) {
this.invalidPageColor = invalidPageColor;
return this;
}
public void load() {
PDFView.this.recycle();
PDFView.this.setOnDrawListener(onDrawListener);
PDFView.this.setOnDrawAllListener(onDrawAllListener);
PDFView.this.setOnPageChangeListener(onPageChangeListener);
PDFView.this.setOnPageScrollListener(onPageScrollListener);
PDFView.this.setOnRenderListener(onRenderListener);
PDFView.this.setOnTapListener(onTapListener);
PDFView.this.setOnPageErrorListener(onPageErrorListener);
PDFView.this.enableSwipe(enableSwipe);
PDFView.this.enableDoubletap(enableDoubletap);
PDFView.this.setDefaultPage(defaultPage);
PDFView.this.setSwipeVertical(!swipeHorizontal);
PDFView.this.enableAnnotationRendering(annotationRendering);
PDFView.this.setScrollHandle(scrollHandle);
PDFView.this.enableAntialiasing(antialiasing);
PDFView.this.setSpacing(spacing);
PDFView.this.setInvalidPageColor(invalidPageColor);
PDFView.this.dragPinchManager.setSwipeVertical(swipeVertical);
PDFView.this.post(new Runnable() {
@Override
public void run() {
if (pageNumbers != null) {
PDFView.this.load(documentSource, password, onLoadCompleteListener, onErrorListener, pageNumbers);
} else {
PDFView.this.load(documentSource, password, onLoadCompleteListener, onErrorListener);
}
}
});
}
}
}
package com.github.barteksc.pdfviewer;
import android.graphics.RectF;
import android.util.Pair;
import com.github.barteksc.pdfviewer.util.Constants;
import com.github.barteksc.pdfviewer.util.MathUtils;
import static com.github.barteksc.pdfviewer.util.Constants.Cache.CACHE_SIZE;
class PagesLoader {
private PDFView pdfView;
// variables set on every call to loadPages()
private int cacheOrder;
private float scaledHeight;
private float scaledWidth;
private Pair<Integer, Integer> colsRows;
private float xOffset;
private float yOffset;
private float rowHeight;
private float colWidth;
private float pageRelativePartWidth;
private float pageRelativePartHeight;
private float partRenderWidth;
private float partRenderHeight;
private int thumbnailWidth;
private int thumbnailHeight;
private float scaledSpacingPx;
private final RectF thumbnailRect = new RectF(0, 0, 1, 1);
private class Holder {
int page;
int row;
int col;
}
PagesLoader(PDFView pdfView) {
this.pdfView = pdfView;
}
private Pair<Integer, Integer> getPageColsRows() {
float ratioX = 1f / pdfView.getOptimalPageWidth();
float ratioY = 1f / pdfView.getOptimalPageHeight();
final float partHeight = (Constants.PART_SIZE * ratioY) / pdfView.getZoom();
final float partWidth = (Constants.PART_SIZE * ratioX) / pdfView.getZoom();
final int nbRows = MathUtils.ceil(1f / partHeight);
final int nbCols = MathUtils.ceil(1f / partWidth);
return new Pair<>(nbCols, nbRows);
}
private int documentPage(int userPage) {
int documentPage = userPage;
if (pdfView.getOriginalUserPages() != null) {
if (userPage < 0 || userPage >= pdfView.getOriginalUserPages().length) {
return -1;
} else {
documentPage = pdfView.getOriginalUserPages()[userPage];
}
}
if (documentPage < 0 || userPage >= pdfView.getDocumentPageCount()) {
return -1;
}
return documentPage;
}
/**
* @param offset
* @param endOffset, if true, then rounding up, else rounding down
* @return
*/
private Holder getPageAndCoordsByOffset(float offset, boolean endOffset) {
Holder holder = new Holder();
float fixOffset = -MathUtils.max(offset, 0);
float row, col;
if (pdfView.isSwipeVertical()) {
holder.page = MathUtils.floor(fixOffset / (scaledHeight + scaledSpacingPx));
row = Math.abs(fixOffset - (scaledHeight + scaledSpacingPx) * holder.page) / rowHeight;
col = xOffset / colWidth;
} else {
holder.page = MathUtils.floor(fixOffset / (scaledWidth + scaledSpacingPx));
col = Math.abs(fixOffset - (scaledWidth + scaledSpacingPx) * holder.page) / colWidth;
row = yOffset / rowHeight;
}
if (endOffset) {
holder.row = MathUtils.ceil(row);
holder.col = MathUtils.ceil(col);
} else {
holder.row = MathUtils.floor(row);
holder.col = MathUtils.floor(col);
}
return holder;
}
private void loadThumbnail(int userPage, int documentPage) {
if (!pdfView.cacheManager.containsThumbnail(userPage, documentPage,
thumbnailWidth, thumbnailHeight, thumbnailRect)) {
pdfView.renderingHandler.addRenderingTask(userPage, documentPage,
thumbnailWidth, thumbnailHeight, thumbnailRect,
true, 0, pdfView.isBestQuality(), pdfView.isAnnotationRendering());
}
}
/**
* @param number if < 0 then row (column) is above view, else row (column) is visible or below view
* @return
*/
private int loadRelative(int number, int nbOfPartsLoadable, boolean belowView) {
int loaded = 0;
float newOffset;
if (pdfView.isSwipeVertical()) {
float rowsHeight = rowHeight * number + 1;
newOffset = pdfView.getCurrentYOffset() - (belowView ? pdfView.getHeight() : 0) - rowsHeight;
} else {
float colsWidth = colWidth * number;
newOffset = pdfView.getCurrentXOffset() - (belowView ? pdfView.getWidth() : 0) - colsWidth;
}
Holder holder = getPageAndCoordsByOffset(newOffset, false);
int documentPage = documentPage(holder.page);
if (documentPage < 0) {
return 0;
}
loadThumbnail(holder.page, documentPage);
if (pdfView.isSwipeVertical()) {
int firstCol = MathUtils.floor(xOffset / colWidth);
firstCol = MathUtils.min(firstCol - 1, 0);
int lastCol = MathUtils.ceil((xOffset + pdfView.getWidth()) / colWidth);
lastCol = MathUtils.max(lastCol + 1, colsRows.first);
for (int col = firstCol; col <= lastCol; col++) {
if (loadCell(holder.page, documentPage, holder.row, col, pageRelativePartWidth, pageRelativePartHeight)) {
loaded++;
}
if (loaded >= nbOfPartsLoadable) {
return loaded;
}
}
} else {
int firstRow = MathUtils.floor(yOffset / rowHeight);
firstRow = MathUtils.min(firstRow - 1, 0);
int lastRow = MathUtils.ceil((yOffset + pdfView.getHeight()) / rowHeight);
lastRow = MathUtils.max(lastRow + 1, colsRows.second);
for (int row = firstRow; row <= lastRow; row++) {
if (loadCell(holder.page, documentPage, row, holder.col, pageRelativePartWidth, pageRelativePartHeight)) {
loaded++;
}
if (loaded >= nbOfPartsLoadable) {
return loaded;
}
}
}
return loaded;
}
public int loadVisible() {
int parts = 0;
Holder firstHolder, lastHolder;
if (pdfView.isSwipeVertical()) {
firstHolder = getPageAndCoordsByOffset(pdfView.getCurrentYOffset(), false);
lastHolder = getPageAndCoordsByOffset(pdfView.getCurrentYOffset() - pdfView.getHeight() + 1, true);
int visibleRows = 0;
if (firstHolder.page == lastHolder.page) {
visibleRows = lastHolder.row - firstHolder.row + 1;
} else {
visibleRows += colsRows.second - firstHolder.row;
for (int page = firstHolder.page + 1; page < lastHolder.page; page++) {
visibleRows += colsRows.second;
}
visibleRows += lastHolder.row + 1;
}
for (int i = 0; i < visibleRows && parts < CACHE_SIZE; i++) {
parts += loadRelative(i, CACHE_SIZE - parts, false);
}
} else {
firstHolder = getPageAndCoordsByOffset(pdfView.getCurrentXOffset(), false);
lastHolder = getPageAndCoordsByOffset(pdfView.getCurrentXOffset() - pdfView.getWidth() + 1, true);
int visibleCols = 0;
if (firstHolder.page == lastHolder.page) {
visibleCols = lastHolder.col - firstHolder.col + 1;
} else {
visibleCols += colsRows.first - firstHolder.col;
for (int page = firstHolder.page + 1; page < lastHolder.page; page++) {
visibleCols += colsRows.first;
}
visibleCols += lastHolder.col + 1;
}
for (int i = 0; i < visibleCols && parts < CACHE_SIZE; i++) {
parts += loadRelative(i, CACHE_SIZE - parts, false);
}
}
int prevDocPage = documentPage(firstHolder.page - 1);
if (prevDocPage >= 0) {
loadThumbnail(firstHolder.page - 1, prevDocPage);
}
int nextDocPage = documentPage(firstHolder.page + 1);
if (nextDocPage >= 0) {
loadThumbnail(firstHolder.page + 1, nextDocPage);
}
return parts;
}
private boolean loadCell(int userPage, int documentPage, int row, int col, float pageRelativePartWidth, float pageRelativePartHeight) {
float relX = pageRelativePartWidth * col;
float relY = pageRelativePartHeight * row;
float relWidth = pageRelativePartWidth;
float relHeight = pageRelativePartHeight;
// Adjust width and height to
// avoid being outside the page
float renderWidth = partRenderWidth;
float renderHeight = partRenderHeight;
if (relX + relWidth > 1) {
relWidth = 1 - relX;
}
if (relY + relHeight > 1) {
relHeight = 1 - relY;
}
renderWidth *= relWidth;
renderHeight *= relHeight;
RectF pageRelativeBounds = new RectF(relX, relY, relX + relWidth, relY + relHeight);
if (renderWidth > 0 && renderHeight > 0) {
if (!pdfView.cacheManager.upPartIfContained(userPage, documentPage, renderWidth, renderHeight, pageRelativeBounds, cacheOrder)) {
pdfView.renderingHandler.addRenderingTask(userPage, documentPage,
renderWidth, renderHeight, pageRelativeBounds, false, cacheOrder,
pdfView.isBestQuality(), pdfView.isAnnotationRendering());
}
cacheOrder++;
return true;
}
return false;
}
public void loadPages() {
scaledHeight = pdfView.toCurrentScale(pdfView.getOptimalPageHeight());
scaledWidth = pdfView.toCurrentScale(pdfView.getOptimalPageWidth());
thumbnailWidth = (int) (pdfView.getOptimalPageWidth() * Constants.THUMBNAIL_RATIO);
thumbnailHeight = (int) (pdfView.getOptimalPageHeight() * Constants.THUMBNAIL_RATIO);
colsRows = getPageColsRows();
xOffset = -MathUtils.max(pdfView.getCurrentXOffset(), 0);
yOffset = -MathUtils.max(pdfView.getCurrentYOffset(), 0);
rowHeight = scaledHeight / colsRows.second;
colWidth = scaledWidth / colsRows.first;
pageRelativePartWidth = 1f / (float) colsRows.first;
pageRelativePartHeight = 1f / (float) colsRows.second;
partRenderWidth = Constants.PART_SIZE / pageRelativePartWidth;
partRenderHeight = Constants.PART_SIZE / pageRelativePartHeight;
cacheOrder = 1;
scaledSpacingPx = pdfView.toCurrentScale(pdfView.getSpacingPx());
scaledSpacingPx -= scaledSpacingPx / pdfView.getPageCount();
int loaded = loadVisible();
if (pdfView.getScrollDir().equals(PDFView.ScrollDir.END)) { // if scrolling to end, preload next view
for (int i = 0; i < Constants.PRELOAD_COUNT && loaded < CACHE_SIZE; i++) {
loaded += loadRelative(i, loaded, true);
}
} else { // if scrolling to start, preload previous view
for (int i = 0; i > -Constants.PRELOAD_COUNT && loaded < CACHE_SIZE; i--) {
loaded += loadRelative(i, loaded, false);
}
}
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.SparseBooleanArray;
import com.github.barteksc.pdfviewer.exception.PageRenderingException;
import com.github.barteksc.pdfviewer.model.PagePart;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
/**
* 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 PdfiumCore pdfiumCore;
private PdfDocument pdfDocument;
private PDFView pdfView;
private RectF renderBounds = new RectF();
private Rect roundedRenderBounds = new Rect();
private Matrix renderMatrix = new Matrix();
private final SparseBooleanArray openedPages = new SparseBooleanArray();
private boolean running = false;
RenderingHandler(Looper looper, PDFView pdfView, PdfiumCore pdfiumCore, PdfDocument pdfDocument) {
super(looper);
this.pdfView = pdfView;
this.pdfiumCore = pdfiumCore;
this.pdfDocument = pdfDocument;
}
void addRenderingTask(int userPage, int page, float width, float height, RectF bounds, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) {
RenderingTask task = new RenderingTask(width, height, bounds, userPage, 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 {
if (openedPages.indexOfKey(renderingTask.page) < 0) {
try {
pdfiumCore.openPage(pdfDocument, renderingTask.page);
openedPages.put(renderingTask.page, true);
} catch (Exception e) {
openedPages.put(renderingTask.page, false);
throw new PageRenderingException(renderingTask.page, e);
}
}
int w = Math.round(renderingTask.width);
int h = Math.round(renderingTask.height);
Bitmap render;
try {
render = Bitmap.createBitmap(w, h, renderingTask.bestQuality ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return null;
}
calculateBounds(w, h, renderingTask.bounds);
if (openedPages.get(renderingTask.page)) {
pdfiumCore.renderPageBitmap(pdfDocument, render, renderingTask.page,
roundedRenderBounds.left, roundedRenderBounds.top,
roundedRenderBounds.width(), roundedRenderBounds.height(), renderingTask.annotationRendering);
} else {
render.eraseColor(pdfView.getInvalidPageColor());
}
return new PagePart(renderingTask.userPage, renderingTask.page, render,
renderingTask.width, renderingTask.height,
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;
int userPage;
boolean thumbnail;
int cacheOrder;
boolean bestQuality;
boolean annotationRendering;
RenderingTask(float width, float height, RectF bounds, int userPage, int page, boolean thumbnail, int cacheOrder, boolean bestQuality, boolean annotationRendering) {
this.page = page;
this.width = width;
this.height = height;
this.bounds = bounds;
this.userPage = userPage;
this.thumbnail = thumbnail;
this.cacheOrder = cacheOrder;
this.bestQuality = bestQuality;
this.annotationRendering = annotationRendering;
}
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.exception;
@Deprecated
public class FileNotFoundException extends RuntimeException {
public FileNotFoundException(String detailMessage) {
super(detailMessage);
}
public FileNotFoundException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
}
}
package com.github.barteksc.pdfviewer.exception;
public class PageRenderingException extends Exception {
private final int page;
public PageRenderingException(int page, Throwable cause) {
super(cause);
this.page = page;
}
public int getPage() {
return page;
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.
* <p>
* 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
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
public interface OnErrorListener {
/**
* Called if error occurred while opening PDF
* @param t Throwable with error
*/
void onError(Throwable t);
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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);
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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);
}
/**
* Copyright 2017 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
public interface OnPageErrorListener {
/**
* Called if error occurred while loading PDF page
* @param t Throwable with error
*/
void onPageError(int page, Throwable t);
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 been scrolled
*/
public interface OnPageScrollListener {
/**
* Called on every move while scrolling
*
* @param page current page index
* @param positionOffset see {@link com.github.barteksc.pdfviewer.PDFView#getPositionOffset()}
*/
void onPageScrolled(int page, float positionOffset);
}
/**
* Copyright 2017 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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;
public interface OnRenderListener {
/**
* Called only once, when document is rendered
* @param nbPages number of pages
* @param pageWidth width of page
* @param pageHeight height of page
*/
void onInitiallyRendered(int nbPages, float pageWidth, float pageHeight);
}
/**
* Copyright 2017 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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.view.MotionEvent;
/**
* Implement this interface to receive events from PDFView
* when view has been touched
*/
public interface OnTapListener {
/**
* Called when the user has a tap gesture, before processing scroll handle toggling
*
* @param e MotionEvent that registered as a confirmed single tap
* @return true if the single tap was handled, false to toggle scroll handle
*/
boolean onTap(MotionEvent e);
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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 userPage;
private int page;
private Bitmap renderedBitmap;
private float width, height;
private RectF pageRelativeBounds;
private boolean thumbnail;
private int cacheOrder;
public PagePart(int userPage, int page, Bitmap renderedBitmap, float width, float height, RectF pageRelativeBounds, boolean thumbnail, int cacheOrder) {
super();
this.userPage = userPage;
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 int getUserPage() {
return userPage;
}
public Bitmap getRenderedBitmap() {
return renderedBitmap;
}
public RectF getPageRelativeBounds() {
return pageRelativeBounds;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
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.getUserPage() == userPage
&& part.getWidth() == width
&& part.getHeight() == height
&& part.getPageRelativeBounds().left == pageRelativeBounds.left
&& part.getPageRelativeBounds().right == pageRelativeBounds.right
&& part.getPageRelativeBounds().top == pageRelativeBounds.top
&& part.getPageRelativeBounds().bottom == pageRelativeBounds.bottom;
}
}
package com.github.barteksc.pdfviewer.scroll;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.R;
import com.github.barteksc.pdfviewer.util.Util;
public class DefaultScrollHandle extends RelativeLayout implements ScrollHandle {
private final static int HANDLE_LONG = 65;
private final static int HANDLE_SHORT = 40;
private final static int DEFAULT_TEXT_SIZE = 16;
private float relativeHandlerMiddle = 0f;
protected TextView textView;
protected Context context;
private boolean inverted;
private PDFView pdfView;
private float currentPos;
private Handler handler = new Handler();
private Runnable hidePageScrollerRunnable = new Runnable() {
@Override
public void run() {
hide();
}
};
public DefaultScrollHandle(Context context) {
this(context, false);
}
public DefaultScrollHandle(Context context, boolean inverted) {
super(context);
this.context = context;
this.inverted = inverted;
textView = new TextView(context);
setVisibility(INVISIBLE);
setTextColor(Color.BLACK);
setTextSize(DEFAULT_TEXT_SIZE);
}
@Override
public void setupLayout(PDFView pdfView) {
int align, width, height;
Drawable background;
// determine handler position, default is right (when scrolling vertically) or bottom (when scrolling horizontally)
if (pdfView.isSwipeVertical()) {
width = HANDLE_LONG;
height = HANDLE_SHORT;
if (inverted) { // left
align = ALIGN_PARENT_LEFT;
background = ContextCompat.getDrawable(context, R.drawable.default_scroll_handle_left);
} else { // right
align = ALIGN_PARENT_RIGHT;
background = ContextCompat.getDrawable(context, R.drawable.default_scroll_handle_right);
}
} else {
width = HANDLE_SHORT;
height = HANDLE_LONG;
if (inverted) { // top
align = ALIGN_PARENT_TOP;
background = ContextCompat.getDrawable(context, R.drawable.default_scroll_handle_top);
} else { // bottom
align = ALIGN_PARENT_BOTTOM;
background = ContextCompat.getDrawable(context, R.drawable.default_scroll_handle_bottom);
}
}
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
setBackgroundDrawable(background);
} else {
setBackground(background);
}
LayoutParams lp = new LayoutParams(Util.getDP(context, width), Util.getDP(context, height));
lp.setMargins(0, 0, 0, 0);
LayoutParams tvlp = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tvlp.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
addView(textView, tvlp);
lp.addRule(align);
pdfView.addView(this, lp);
this.pdfView = pdfView;
}
@Override
public void destroyLayout() {
pdfView.removeView(this);
}
@Override
public void setScroll(float position) {
if (!shown()) {
show();
} else {
handler.removeCallbacks(hidePageScrollerRunnable);
}
setPosition((pdfView.isSwipeVertical() ? pdfView.getHeight() : pdfView.getWidth()) * position);
}
private void setPosition(float pos) {
if (Float.isInfinite(pos) || Float.isNaN(pos)) {
return;
}
float pdfViewSize;
if (pdfView.isSwipeVertical()) {
pdfViewSize = pdfView.getHeight();
} else {
pdfViewSize = pdfView.getWidth();
}
pos -= relativeHandlerMiddle;
if (pos < 0) {
pos = 0;
} else if (pos > pdfViewSize - Util.getDP(context, HANDLE_SHORT)) {
pos = pdfViewSize - Util.getDP(context, HANDLE_SHORT);
}
if (pdfView.isSwipeVertical()) {
setY(pos);
} else {
setX(pos);
}
calculateMiddle();
invalidate();
}
private void calculateMiddle() {
float pos, viewSize, pdfViewSize;
if (pdfView.isSwipeVertical()) {
pos = getY();
viewSize = getHeight();
pdfViewSize = pdfView.getHeight();
} else {
pos = getX();
viewSize = getWidth();
pdfViewSize = pdfView.getWidth();
}
relativeHandlerMiddle = ((pos + relativeHandlerMiddle) / pdfViewSize) * viewSize;
}
@Override
public void hideDelayed() {
handler.postDelayed(hidePageScrollerRunnable, 1000);
}
@Override
public void setPageNum(int pageNum) {
String text = String.valueOf(pageNum);
if (!textView.getText().equals(text)) {
textView.setText(text);
}
}
@Override
public boolean shown() {
return getVisibility() == VISIBLE;
}
@Override
public void show() {
setVisibility(VISIBLE);
}
@Override
public void hide() {
setVisibility(INVISIBLE);
}
public void setTextColor(int color) {
textView.setTextColor(color);
}
/**
* @param size text size in dp
*/
public void setTextSize(int size) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, size);
}
private boolean isPDFViewReady() {
return pdfView != null && pdfView.getPageCount() > 0 && !pdfView.documentFitsView();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isPDFViewReady()) {
return super.onTouchEvent(event);
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
pdfView.stopFling();
handler.removeCallbacks(hidePageScrollerRunnable);
if (pdfView.isSwipeVertical()) {
currentPos = event.getRawY() - getY();
} else {
currentPos = event.getRawX() - getX();
}
case MotionEvent.ACTION_MOVE:
if (pdfView.isSwipeVertical()) {
setPosition(event.getRawY() - currentPos + relativeHandlerMiddle);
pdfView.setPositionOffset(relativeHandlerMiddle / (float) getHeight(), false);
} else {
setPosition(event.getRawX() - currentPos + relativeHandlerMiddle);
pdfView.setPositionOffset(relativeHandlerMiddle / (float) getWidth(), false);
}
return true;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
hideDelayed();
return true;
}
return super.onTouchEvent(event);
}
}
package com.github.barteksc.pdfviewer.scroll;
import com.github.barteksc.pdfviewer.PDFView;
public interface ScrollHandle {
/**
* Used to move the handle, called internally by PDFView
*
* @param position current scroll ratio between 0 and 1
*/
void setScroll(float position);
/**
* Method called by PDFView after setting scroll handle.
* Do not call this method manually.
* For usage sample see {@link DefaultScrollHandle}
*
* @param pdfView PDFView instance
*/
void setupLayout(PDFView pdfView);
/**
* Method called by PDFView when handle should be removed from layout
* Do not call this method manually.
*/
void destroyLayout();
/**
* Set page number displayed on handle
*
* @param pageNum page number
*/
void setPageNum(int pageNum);
/**
* Get handle visibility
*
* @return true if handle is visible, false otherwise
*/
boolean shown();
/**
* Show handle
*/
void show();
/**
* Hide handle immediately
*/
void hide();
/**
* Hide handle after some time (defined by implementation)
*/
void hideDelayed();
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import com.github.barteksc.pdfviewer.util.FileUtils;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.File;
import java.io.IOException;
public class AssetSource implements DocumentSource {
private final String assetName;
public AssetSource(String assetName) {
this.assetName = assetName;
}
@Override
public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
File f = FileUtils.fileFromAsset(context, assetName);
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
return core.newDocument(pfd, password);
}
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.IOException;
public class ByteArraySource implements DocumentSource {
private byte[] data;
public ByteArraySource(byte[] data) {
this.data = data;
}
@Override
public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
return core.newDocument(data, password);
}
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.IOException;
public interface DocumentSource {
PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException;
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.File;
import java.io.IOException;
public class FileSource implements DocumentSource {
private File file;
public FileSource(File file) {
this.file = file;
}
@Override
public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return core.newDocument(pfd, password);
}
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import com.github.barteksc.pdfviewer.util.Util;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.IOException;
import java.io.InputStream;
public class InputStreamSource implements DocumentSource {
private InputStream inputStream;
public InputStreamSource(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
return core.newDocument(Util.toByteArray(inputStream), password);
}
}
/*
* Copyright (C) 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.source;
import android.content.Context;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.io.IOException;
public class UriSource implements DocumentSource {
private Uri uri;
public UriSource(Uri uri) {
this.uri = uri;
}
@Override
public PdfDocument createDocument(Context context, PdfiumCore core, String password) throws IOException {
ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
return core.newDocument(pfd, password);
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p>
* 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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<Integer> 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
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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;
/** Number of preloaded rows or columns */
public static int PRELOAD_COUNT = 7;
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 = 6;
}
public static class Pinch {
public static float MAXIMUM_ZOOM = 10;
public static float MINIMUM_ZOOM = 1;
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 android.content.Context;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class FileUtils {
private FileUtils() {
// Prevents instantiation
}
public static File fileFromAsset(Context context, String assetName) throws IOException {
File outFile = new File(context.getCacheDir(), assetName + "-pdfview.pdf");
if (assetName.contains("/")) {
outFile.getParentFile().mkdirs();
}
copy(context.getAssets().open(assetName), outFile);
return outFile;
}
public static void copy(InputStream inputStream, File output) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(output);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} finally {
if (outputStream != null) {
outputStream.close();
}
}
}
}
}
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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 <b>number</b> 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 <b>number</b> 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 (C) 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 android.content.Context;
import android.util.TypedValue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Util {
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
public static int getDP(Context context, int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
}
public static byte[] toByteArray(InputStream inputStream) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int n;
while (-1 != (n = inputStream.read(buffer))) {
os.write(buffer, 0, n);
}
return os.toByteArray();
}
}
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:color="#6C7A89"
android:width="1dp" />
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp" />
<solid android:color="#DADFE1" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/default_scroll_handle_right"
android:fromDegrees="180"
android:toDegrees="180"
android:visible="true" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:color="#6C7A89"
android:width="1dp" />
<corners
android:bottomLeftRadius="10dp"
android:topLeftRadius="10dp" />
<solid android:color="#DADFE1" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/default_scroll_handle_bottom"
android:fromDegrees="180"
android:toDegrees="180"
android:visible="true" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ScrollBar">
<attr name="sb_handlerColor" format="color|reference" />
<attr name="sb_indicatorColor" format="color|reference" />
<attr name="sb_indicatorTextColor" format="color|reference" />
<attr name="sb_horizontal" format="boolean|reference" />
</declare-styleable>
</resources>
\ No newline at end of file
buildscript {
ext {
kotlin_version = '1.8.0'
}
repositories {
mavenCentral()
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
// classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
}
}
allprojects {
repositories {
mavenCentral()
google()
jcenter()
}
}
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
\ No newline at end of file
#Tue Oct 31 21:04:38 CET 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@REM
@REM Copyright 2014 Joan Zapata
@REM
@REM This file is part of Android-pdfview.
@REM
@REM Android-pdfview is free software: you can redistribute it and/or modify
@REM it under the terms of the GNU General Public License as published by
@REM the Free Software Foundation, either version 3 of the License, or
@REM (at your option) any later version.
@REM
@REM Android-pdfview is distributed in the hope that it will be useful,
@REM but WITHOUT ANY WARRANTY; without even the implied warranty of
@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@REM GNU General Public License for more details.
@REM
@REM You should have received a copy of the GNU General Public License
@REM along with Android-pdfview. If not, see <http://www.gnu.org/licenses/>.
@REM
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
namespace = "com.github.barteksc.sample"
compileSdk = 34
defaultConfig {
minSdkVersion 24
targetSdkVersion 34
versionCode 3
versionName "2.0.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
api project(':android-pdf-viewer')
implementation("androidx.appcompat:appcompat:1.7.0")
implementation "androidx.core:core-ktx:$kotlin_version"
}
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keep class your.package.** { *; }
-dontwarn your.package.**
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.barteksc.sample">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.Light">
<activity
android:name="PDFViewActivity"
android:exported="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
/**
* Copyright 2016 Bartosz Schiller
* <p/>
* 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
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* 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.sample;
import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.OpenableColumns;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
import com.github.barteksc.pdfviewer.listener.OnPageErrorListener;
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
import com.shockwave.pdfium.PdfDocument;
import com.shockwave.pdfium.PdfiumCore;
import java.util.List;
public class PDFViewActivity extends AppCompatActivity implements OnPageChangeListener, OnLoadCompleteListener,
OnPageErrorListener {
private static final String TAG = PDFViewActivity.class.getSimpleName();
private final static int REQUEST_CODE = 42;
public static final int PERMISSION_CODE = 42042;
public static final String SAMPLE_FILE = "sample.pdf";
public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
PDFView pdfView;
Uri uri;
Integer pageNumber = 0;
String pdfFileName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pdfView = (PDFView) findViewById(R.id.pdfView);
afterViews();
pickFile();
long value = new PdfiumCore(this).TestJniFun();
Toast.makeText(this, Long.toString(value), Toast.LENGTH_SHORT).show();
}
@Override
protected void onRestart() {
super.onRestart();
}
void pickFile() {
int permissionCheck = ContextCompat.checkSelfPermission(this,
READ_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{READ_EXTERNAL_STORAGE},
PERMISSION_CODE
);
return;
}
launchPicker();
}
void launchPicker() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("application/pdf");
try {
startActivityForResult(intent, REQUEST_CODE);
} catch (ActivityNotFoundException e) {
//alert user that file manager not working
Toast.makeText(this, R.string.toast_pick_file_error, Toast.LENGTH_SHORT).show();
}
}
void afterViews() {
// pdfView.setBackgroundColor(Color.LTGRAY);
if (uri != null) {
displayFromUri(uri);
} else {
displayFromAsset(SAMPLE_FILE);
}
// setTitle(pdfFileName);
}
private void displayFromAsset(String assetFileName) {
pdfFileName = assetFileName;
if (pdfView == null) {
return;
}
pdfView.fromAsset(SAMPLE_FILE)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.onPageError(this)
.load();
}
private void displayFromUri(Uri uri) {
pdfFileName = getFileName(uri);
pdfView.fromUri(uri)
.defaultPage(pageNumber)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.spacing(10) // in dp
.onPageError(this)
.load();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
onResult(resultCode, data);
}
public void onResult(int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {
uri = intent.getData();
displayFromUri(uri);
}
}
@Override
public void onPageChanged(int page, int pageCount) {
pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
}
@SuppressLint("Range")
public String getFileName(Uri uri) {
String result = null;
if (uri.getScheme().equals("content")) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} finally {
if (cursor != null) {
cursor.close();
}
}
}
if (result == null) {
result = uri.getLastPathSegment();
}
return result;
}
@Override
public void loadComplete(int nbPages) {
PdfDocument.Meta meta = pdfView.getDocumentMeta();
Log.e(TAG, "title = " + meta.getTitle());
Log.e(TAG, "author = " + meta.getAuthor());
Log.e(TAG, "subject = " + meta.getSubject());
Log.e(TAG, "keywords = " + meta.getKeywords());
Log.e(TAG, "creator = " + meta.getCreator());
Log.e(TAG, "producer = " + meta.getProducer());
Log.e(TAG, "creationDate = " + meta.getCreationDate());
Log.e(TAG, "modDate = " + meta.getModDate());
printBookmarksTree(pdfView.getTableOfContents(), "-");
}
public void printBookmarksTree(List<PdfDocument.Bookmark> tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
/**
* Listener for response to user permission request
*
* @param requestCode Check that permission request code matches
* @param permissions Permissions that requested
* @param grantResults Whether permissions granted
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_CODE) {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
launchPicker();
}
}
}
@Override
public void onPageError(int page, Throwable t) {
Log.e(TAG, "Cannot load page " + page);
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.barteksc.pdfviewer.PDFView
android:id="@+id/pdfView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/pickFile"
android:icon="@drawable/ic_open_in_browser_grey_700_48dp"
android:title="@string/pick_file"
app:showAsAction="always" />
</menu>
\ No newline at end of file
<resources>
<string name="app_name">AndroidPdfViewer demo</string>
<string name="pick_file">Pick file</string>
<string name="toast_pick_file_error">Unable to pick file. Check status of file manager.</string>
</resources>
\ No newline at end of file
<resources>
</resources>
\ No newline at end of file
include ':android-pdf-viewer'
include ':sample'
include ':PdfiumAndroid'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment