1 package cz.cvut.fel.dce.qrscanner.mupdf;
3 import android.content.Context;
4 import android.graphics.Bitmap;
5 import android.graphics.PointF;
6 import android.graphics.RectF;
8 import java.util.ArrayList;
10 import cz.cvut.fel.dce.qrscanner.R;
12 public class MuPDFCore
14 /* load our native library */
16 System.loadLibrary("mupdf");
19 /* Readable members */
20 private int numPages = -1;
21 private float pageWidth;
22 private float pageHeight;
24 private byte fileBuffer[];
25 private String file_format;
26 private boolean isUnencryptedPDF;
27 private final boolean wasOpenedFromBuffer;
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,
40 int patchX, int patchY,
41 int patchW, int patchH,
43 private native void updatePageInternal(Bitmap bitmap,
46 int patchX, int patchY,
47 int patchW, int patchH,
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);
83 public native boolean javascriptSupported();
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);
97 class PassClickResult {
98 public final boolean changed;
100 public PassClickResult(boolean _changed) {
104 public void acceptVisitor(PassClickResultVisitor visitor) {
108 class PassClickResultText extends PassClickResult {
109 public final String text;
111 public PassClickResultText(boolean _changed, String _text) {
116 public void acceptVisitor(PassClickResultVisitor visitor) {
117 visitor.visitText(this);
121 class PassClickResultChoice extends PassClickResult {
122 public final String [] options;
123 public final String [] selected;
125 public PassClickResultChoice(boolean _changed, String [] _options, String [] _selected) {
128 selected = _selected;
131 public void acceptVisitor(PassClickResultVisitor visitor) {
132 visitor.visitChoice(this);
136 class PassClickResultSignature extends PassClickResult {
137 public final SignatureState state;
139 public PassClickResultSignature(boolean _changed, int _state) {
141 state = SignatureState.values()[_state];
144 public void acceptVisitor(PassClickResultVisitor visitor) {
145 visitor.visitSignature(this);
151 private final long cookiePtr;
155 cookiePtr = createCookie();
157 throw new OutOfMemoryError();
162 abortCookie(cookiePtr);
165 public void destroy()
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);
173 public MuPDFCore(Context context, String filename) throws Exception
175 globals = openFile(filename);
178 throw new Exception(String.format(context.getString(R.string.cannot_open_file_Path), filename));
180 file_format = fileFormatInternal();
181 isUnencryptedPDF = isUnencryptedPDFInternal();
182 wasOpenedFromBuffer = false;
185 public MuPDFCore(Context context, byte buffer[], String magic) throws Exception {
187 globals = openBuffer(magic != null ? magic : "");
190 throw new Exception(context.getString(R.string.cannot_open_buffer));
192 file_format = fileFormatInternal();
193 isUnencryptedPDF = isUnencryptedPDFInternal();
194 wasOpenedFromBuffer = true;
197 public int countPages()
200 numPages = countPagesSynchronized();
205 public String fileFormat()
210 public boolean isUnencryptedPDF()
212 return isUnencryptedPDF;
215 public boolean wasOpenedFromBuffer()
217 return wasOpenedFromBuffer;
220 private synchronized int countPagesSynchronized() {
221 return countPagesInternal();
225 private void gotoPage(int page)
227 if (page > numPages-1)
231 gotoPageInternal(page);
232 this.pageWidth = getPageWidth();
233 this.pageHeight = getPageHeight();
236 public synchronized PointF getPageSize(int page) {
238 return new PointF(pageWidth, pageHeight);
241 public MuPDFAlert waitForAlert() {
242 MuPDFAlertInternal alert = waitForAlertInternal();
243 return alert != null ? alert.toAlert() : null;
246 public void replyToAlert(MuPDFAlert alert) {
247 replyToAlertInternal(new MuPDFAlertInternal(alert));
250 public void stopAlerts() {
251 stopAlertsInternal();
254 public void startAlerts() {
255 startAlertsInternal();
258 public synchronized void onDestroy() {
263 public synchronized void drawPage(Bitmap bm, int page,
264 int pageW, int pageH,
265 int patchX, int patchY,
266 int patchW, int patchH,
269 drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
272 public synchronized void updatePage(Bitmap bm, int page,
273 int pageW, int pageH,
274 int patchX, int patchY,
275 int patchW, int patchH,
277 updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
280 public synchronized PassClickResult passClickEvent(int page, float x, float y) {
281 boolean changed = passClickEventInternal(page, x, y) != 0;
283 switch (WidgetType.values()[getFocusedWidgetTypeInternal()])
286 return new PassClickResultText(changed, getFocusedWidgetTextInternal());
289 return new PassClickResultChoice(changed, getFocusedWidgetChoiceOptions(), getFocusedWidgetChoiceSelected());
291 return new PassClickResultSignature(changed, getFocusedWidgetSignatureState());
293 return new PassClickResult(changed);
298 public synchronized boolean setFocusedWidgetText(int page, String text) {
301 success = setFocusedWidgetTextInternal(text) != 0 ? true : false;
306 public synchronized void setFocusedWidgetChoiceSelected(String [] selected) {
307 setFocusedWidgetChoiceSelectedInternal(selected);
310 public synchronized String checkFocusedSignature() {
311 return checkFocusedSignatureInternal();
314 public synchronized boolean signFocusedSignature(String keyFile, String password) {
315 return signFocusedSignatureInternal(keyFile, password);
318 public synchronized LinkInfo [] getPageLinks(int page) {
319 return getPageLinksInternal(page);
322 public synchronized RectF [] getWidgetAreas(int page) {
323 return getWidgetAreasInternal(page);
326 public synchronized Annotation [] getAnnoations(int page) {
327 return getAnnotationsInternal(page);
330 public synchronized RectF [] searchPage(int page, String text) {
332 return searchPage(text);
335 public synchronized byte[] html(int page) {
340 public synchronized TextWord [][] textLines(int page) {
342 TextChar[][][][] chars = text();
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[]>();
349 for (TextChar[][][] bl: chars) {
352 for (TextChar[][] ln: bl) {
353 ArrayList<TextWord> wds = new ArrayList<TextWord>();
354 TextWord wd = new TextWord();
356 for (TextChar[] sp: ln) {
357 for (TextChar tc: sp) {
360 } else if (wd.w.length() > 0) {
367 if (wd.w.length() > 0)
371 lns.add(wds.toArray(new TextWord[wds.size()]));
375 return lns.toArray(new TextWord[lns.size()][]);
378 public synchronized void addMarkupAnnotation(int page, PointF[] quadPoints, Annotation.Type type) {
380 addMarkupAnnotationInternal(quadPoints, type.ordinal());
383 public synchronized void addInkAnnotation(int page, PointF[][] arcs) {
385 addInkAnnotationInternal(arcs);
388 public synchronized void deleteAnnotation(int page, int annot_index) {
390 deleteAnnotationInternal(annot_index);
393 public synchronized boolean hasOutline() {
394 return hasOutlineInternal();
397 public synchronized OutlineItem [] getOutline() {
398 return getOutlineInternal();
401 public synchronized boolean needsPassword() {
402 return needsPasswordInternal();
405 public synchronized boolean authenticatePassword(String password) {
406 return authenticatePasswordInternal(password);
409 public synchronized boolean hasChanges() {
410 return hasChangesInternal();
413 public synchronized void save() {