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