Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7859 views
1
package com.artifex.mupdfdemo;
2
import java.util.ArrayList;
3
4
import android.content.Context;
5
import android.graphics.Bitmap;
6
import android.graphics.Bitmap.Config;
7
import android.graphics.PointF;
8
import android.graphics.RectF;
9
10
public class MuPDFCore
11
{
12
/* load our native library */
13
static {
14
System.loadLibrary("mupdf");
15
}
16
17
/* Readable members */
18
private int numPages = -1;
19
private float pageWidth;
20
private float pageHeight;
21
private long globals;
22
private byte fileBuffer[];
23
private String file_format;
24
private boolean isUnencryptedPDF;
25
private final boolean wasOpenedFromBuffer;
26
27
/* The native functions */
28
private native long openFile(String filename);
29
private native long openBuffer(String magic);
30
private native String fileFormatInternal();
31
private native boolean isUnencryptedPDFInternal();
32
private native int countPagesInternal();
33
private native void gotoPageInternal(int localActionPageNum);
34
private native float getPageWidth();
35
private native float getPageHeight();
36
private native void drawPage(Bitmap bitmap,
37
int pageW, int pageH,
38
int patchX, int patchY,
39
int patchW, int patchH,
40
long cookiePtr);
41
private native void updatePageInternal(Bitmap bitmap,
42
int page,
43
int pageW, int pageH,
44
int patchX, int patchY,
45
int patchW, int patchH,
46
long cookiePtr);
47
private native RectF[] searchPage(String text);
48
private native TextChar[][][][] text();
49
private native byte[] textAsHtml();
50
private native void addMarkupAnnotationInternal(PointF[] quadPoints, int type);
51
private native void addInkAnnotationInternal(PointF[][] arcs);
52
private native void deleteAnnotationInternal(int annot_index);
53
private native int passClickEventInternal(int page, float x, float y);
54
private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
55
private native String [] getFocusedWidgetChoiceSelected();
56
private native String [] getFocusedWidgetChoiceOptions();
57
private native int getFocusedWidgetSignatureState();
58
private native String checkFocusedSignatureInternal();
59
private native boolean signFocusedSignatureInternal(String keyFile, String password);
60
private native int setFocusedWidgetTextInternal(String text);
61
private native String getFocusedWidgetTextInternal();
62
private native int getFocusedWidgetTypeInternal();
63
private native LinkInfo [] getPageLinksInternal(int page);
64
private native RectF[] getWidgetAreasInternal(int page);
65
private native Annotation[] getAnnotationsInternal(int page);
66
private native OutlineItem [] getOutlineInternal();
67
private native boolean hasOutlineInternal();
68
private native boolean needsPasswordInternal();
69
private native boolean authenticatePasswordInternal(String password);
70
private native MuPDFAlertInternal waitForAlertInternal();
71
private native void replyToAlertInternal(MuPDFAlertInternal alert);
72
private native void startAlertsInternal();
73
private native void stopAlertsInternal();
74
private native void destroying();
75
private native boolean hasChangesInternal();
76
private native void saveInternal();
77
private native long createCookie();
78
private native void destroyCookie(long cookie);
79
private native void abortCookie(long cookie);
80
81
public native boolean javascriptSupported();
82
83
public class Cookie
84
{
85
private final long cookiePtr;
86
87
public Cookie()
88
{
89
cookiePtr = createCookie();
90
if (cookiePtr == 0)
91
throw new OutOfMemoryError();
92
}
93
94
public void abort()
95
{
96
abortCookie(cookiePtr);
97
}
98
99
public void destroy()
100
{
101
// We could do this in finalize, but there's no guarantee that
102
// a finalize will occur before the muPDF context occurs.
103
destroyCookie(cookiePtr);
104
}
105
}
106
107
public MuPDFCore(Context context, String filename) throws Exception
108
{
109
globals = openFile(filename);
110
if (globals == 0)
111
{
112
throw new Exception(String.format(context.getString(R.string.cannot_open_file_Path), filename));
113
}
114
file_format = fileFormatInternal();
115
isUnencryptedPDF = isUnencryptedPDFInternal();
116
wasOpenedFromBuffer = false;
117
}
118
119
public MuPDFCore(Context context, byte buffer[], String magic) throws Exception {
120
fileBuffer = buffer;
121
globals = openBuffer(magic != null ? magic : "");
122
if (globals == 0)
123
{
124
throw new Exception(context.getString(R.string.cannot_open_buffer));
125
}
126
file_format = fileFormatInternal();
127
isUnencryptedPDF = isUnencryptedPDFInternal();
128
wasOpenedFromBuffer = true;
129
}
130
131
public int countPages()
132
{
133
if (numPages < 0)
134
numPages = countPagesSynchronized();
135
return numPages;
136
}
137
138
public String fileFormat()
139
{
140
return file_format;
141
}
142
143
public boolean isUnencryptedPDF()
144
{
145
return isUnencryptedPDF;
146
}
147
148
public boolean wasOpenedFromBuffer()
149
{
150
return wasOpenedFromBuffer;
151
}
152
153
private synchronized int countPagesSynchronized() {
154
return countPagesInternal();
155
}
156
157
/* Shim function */
158
private void gotoPage(int page)
159
{
160
if (page > numPages-1)
161
page = numPages-1;
162
else if (page < 0)
163
page = 0;
164
gotoPageInternal(page);
165
this.pageWidth = getPageWidth();
166
this.pageHeight = getPageHeight();
167
}
168
169
public synchronized PointF getPageSize(int page) {
170
gotoPage(page);
171
return new PointF(pageWidth, pageHeight);
172
}
173
174
public MuPDFAlert waitForAlert() {
175
MuPDFAlertInternal alert = waitForAlertInternal();
176
return alert != null ? alert.toAlert() : null;
177
}
178
179
public void replyToAlert(MuPDFAlert alert) {
180
replyToAlertInternal(new MuPDFAlertInternal(alert));
181
}
182
183
public void stopAlerts() {
184
stopAlertsInternal();
185
}
186
187
public void startAlerts() {
188
startAlertsInternal();
189
}
190
191
public synchronized void onDestroy() {
192
destroying();
193
globals = 0;
194
}
195
196
public synchronized void drawPage(Bitmap bm, int page,
197
int pageW, int pageH,
198
int patchX, int patchY,
199
int patchW, int patchH,
200
MuPDFCore.Cookie cookie) {
201
gotoPage(page);
202
drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
203
}
204
205
public synchronized void updatePage(Bitmap bm, int page,
206
int pageW, int pageH,
207
int patchX, int patchY,
208
int patchW, int patchH,
209
MuPDFCore.Cookie cookie) {
210
updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
211
}
212
213
public synchronized PassClickResult passClickEvent(int page, float x, float y) {
214
boolean changed = passClickEventInternal(page, x, y) != 0;
215
216
switch (WidgetType.values()[getFocusedWidgetTypeInternal()])
217
{
218
case TEXT:
219
return new PassClickResultText(changed, getFocusedWidgetTextInternal());
220
case LISTBOX:
221
case COMBOBOX:
222
return new PassClickResultChoice(changed, getFocusedWidgetChoiceOptions(), getFocusedWidgetChoiceSelected());
223
case SIGNATURE:
224
return new PassClickResultSignature(changed, getFocusedWidgetSignatureState());
225
default:
226
return new PassClickResult(changed);
227
}
228
229
}
230
231
public synchronized boolean setFocusedWidgetText(int page, String text) {
232
boolean success;
233
gotoPage(page);
234
success = setFocusedWidgetTextInternal(text) != 0 ? true : false;
235
236
return success;
237
}
238
239
public synchronized void setFocusedWidgetChoiceSelected(String [] selected) {
240
setFocusedWidgetChoiceSelectedInternal(selected);
241
}
242
243
public synchronized String checkFocusedSignature() {
244
return checkFocusedSignatureInternal();
245
}
246
247
public synchronized boolean signFocusedSignature(String keyFile, String password) {
248
return signFocusedSignatureInternal(keyFile, password);
249
}
250
251
public synchronized LinkInfo [] getPageLinks(int page) {
252
return getPageLinksInternal(page);
253
}
254
255
public synchronized RectF [] getWidgetAreas(int page) {
256
return getWidgetAreasInternal(page);
257
}
258
259
public synchronized Annotation [] getAnnoations(int page) {
260
return getAnnotationsInternal(page);
261
}
262
263
public synchronized RectF [] searchPage(int page, String text) {
264
gotoPage(page);
265
return searchPage(text);
266
}
267
268
public synchronized byte[] html(int page) {
269
gotoPage(page);
270
return textAsHtml();
271
}
272
273
public synchronized TextWord [][] textLines(int page) {
274
gotoPage(page);
275
TextChar[][][][] chars = text();
276
277
// The text of the page held in a hierarchy (blocks, lines, spans).
278
// Currently we don't need to distinguish the blocks level or
279
// the spans, and we need to collect the text into words.
280
ArrayList<TextWord[]> lns = new ArrayList<TextWord[]>();
281
282
for (TextChar[][][] bl: chars) {
283
if (bl == null)
284
continue;
285
for (TextChar[][] ln: bl) {
286
ArrayList<TextWord> wds = new ArrayList<TextWord>();
287
TextWord wd = new TextWord();
288
289
for (TextChar[] sp: ln) {
290
for (TextChar tc: sp) {
291
if (tc.c != ' ') {
292
wd.Add(tc);
293
} else if (wd.w.length() > 0) {
294
wds.add(wd);
295
wd = new TextWord();
296
}
297
}
298
}
299
300
if (wd.w.length() > 0)
301
wds.add(wd);
302
303
if (wds.size() > 0)
304
lns.add(wds.toArray(new TextWord[wds.size()]));
305
}
306
}
307
308
return lns.toArray(new TextWord[lns.size()][]);
309
}
310
311
public synchronized void addMarkupAnnotation(int page, PointF[] quadPoints, Annotation.Type type) {
312
gotoPage(page);
313
addMarkupAnnotationInternal(quadPoints, type.ordinal());
314
}
315
316
public synchronized void addInkAnnotation(int page, PointF[][] arcs) {
317
gotoPage(page);
318
addInkAnnotationInternal(arcs);
319
}
320
321
public synchronized void deleteAnnotation(int page, int annot_index) {
322
gotoPage(page);
323
deleteAnnotationInternal(annot_index);
324
}
325
326
public synchronized boolean hasOutline() {
327
return hasOutlineInternal();
328
}
329
330
public synchronized OutlineItem [] getOutline() {
331
return getOutlineInternal();
332
}
333
334
public synchronized boolean needsPassword() {
335
return needsPasswordInternal();
336
}
337
338
public synchronized boolean authenticatePassword(String password) {
339
return authenticatePasswordInternal(password);
340
}
341
342
public synchronized boolean hasChanges() {
343
return hasChangesInternal();
344
}
345
346
public synchronized void save() {
347
saveInternal();
348
}
349
}
350
351