1 package cz.cvut.fel.dce.qrscanner.mupdf;
2 import java.util.ArrayList;
4 import android.content.Context;
5 import android.graphics.Bitmap;
6 import android.graphics.PointF;
7 import android.graphics.RectF;
9 import cz.cvut.fel.dce.qrscanner.R;
11 public class MuPDFCore
13 /* load our native library */
15 System.loadLibrary("mupdf");
18 /* Readable members */
19 private int numPages = -1;
20 private float pageWidth;
21 private float pageHeight;
23 private byte fileBuffer[];
24 private String file_format;
25 private boolean isUnencryptedPDF;
26 private final boolean wasOpenedFromBuffer;
28 /* The native functions */
29 private native long openFile(String filename);
30 private native long openBuffer(String magic);
31 private native String fileFormatInternal();
32 private native boolean isUnencryptedPDFInternal();
33 private native int countPagesInternal();
34 private native void gotoPageInternal(int localActionPageNum);
35 private native float getPageWidth();
36 private native float getPageHeight();
37 private native void drawPage(Bitmap bitmap,
39 int patchX, int patchY,
40 int patchW, int patchH,
42 private native void updatePageInternal(Bitmap bitmap,
45 int patchX, int patchY,
46 int patchW, int patchH,
48 private native RectF[] searchPage(String text);
49 private native TextChar[][][][] text();
50 private native byte[] textAsHtml();
51 private native void addMarkupAnnotationInternal(PointF[] quadPoints, int type);
52 private native void addInkAnnotationInternal(PointF[][] arcs);
53 private native void deleteAnnotationInternal(int annot_index);
54 private native int passClickEventInternal(int page, float x, float y);
55 private native void setFocusedWidgetChoiceSelectedInternal(String [] selected);
56 private native String [] getFocusedWidgetChoiceSelected();
57 private native String [] getFocusedWidgetChoiceOptions();
58 private native int getFocusedWidgetSignatureState();
59 private native String checkFocusedSignatureInternal();
60 private native boolean signFocusedSignatureInternal(String keyFile, String password);
61 private native int setFocusedWidgetTextInternal(String text);
62 private native String getFocusedWidgetTextInternal();
63 private native int getFocusedWidgetTypeInternal();
64 private native LinkInfo [] getPageLinksInternal(int page);
65 private native RectF[] getWidgetAreasInternal(int page);
66 private native Annotation[] getAnnotationsInternal(int page);
67 private native OutlineItem [] getOutlineInternal();
68 private native boolean hasOutlineInternal();
69 private native boolean needsPasswordInternal();
70 private native boolean authenticatePasswordInternal(String password);
71 private native MuPDFAlertInternal waitForAlertInternal();
72 private native void replyToAlertInternal(MuPDFAlertInternal alert);
73 private native void startAlertsInternal();
74 private native void stopAlertsInternal();
75 private native void destroying();
76 private native boolean hasChangesInternal();
77 private native void saveInternal();
78 private native long createCookie();
79 private native void destroyCookie(long cookie);
80 private native void abortCookie(long cookie);
82 public native boolean javascriptSupported();
86 private final long cookiePtr;
90 cookiePtr = createCookie();
92 throw new OutOfMemoryError();
97 abortCookie(cookiePtr);
100 public void destroy()
102 // We could do this in finalize, but there's no guarantee that
103 // a finalize will occur before the muPDF context occurs.
104 destroyCookie(cookiePtr);
108 public MuPDFCore(Context context, String filename) throws Exception
110 globals = openFile(filename);
113 throw new Exception(String.format(context.getString(R.string.cannot_open_file_Path), filename));
115 file_format = fileFormatInternal();
116 isUnencryptedPDF = isUnencryptedPDFInternal();
117 wasOpenedFromBuffer = false;
120 public MuPDFCore(Context context, byte buffer[], String magic) throws Exception {
122 globals = openBuffer(magic != null ? magic : "");
125 throw new Exception(context.getString(R.string.cannot_open_buffer));
127 file_format = fileFormatInternal();
128 isUnencryptedPDF = isUnencryptedPDFInternal();
129 wasOpenedFromBuffer = true;
132 public int countPages()
135 numPages = countPagesSynchronized();
140 public String fileFormat()
145 public boolean isUnencryptedPDF()
147 return isUnencryptedPDF;
150 public boolean wasOpenedFromBuffer()
152 return wasOpenedFromBuffer;
155 private synchronized int countPagesSynchronized() {
156 return countPagesInternal();
160 private void gotoPage(int page)
162 if (page > numPages-1)
166 gotoPageInternal(page);
167 this.pageWidth = getPageWidth();
168 this.pageHeight = getPageHeight();
171 public synchronized PointF getPageSize(int page) {
173 return new PointF(pageWidth, pageHeight);
176 public MuPDFAlert waitForAlert() {
177 MuPDFAlertInternal alert = waitForAlertInternal();
178 return alert != null ? alert.toAlert() : null;
181 public void replyToAlert(MuPDFAlert alert) {
182 replyToAlertInternal(new MuPDFAlertInternal(alert));
185 public void stopAlerts() {
186 stopAlertsInternal();
189 public void startAlerts() {
190 startAlertsInternal();
193 public synchronized void onDestroy() {
198 public synchronized void drawPage(Bitmap bm, int page,
199 int pageW, int pageH,
200 int patchX, int patchY,
201 int patchW, int patchH,
202 MuPDFCore.Cookie cookie) {
204 drawPage(bm, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
207 public synchronized void updatePage(Bitmap bm, int page,
208 int pageW, int pageH,
209 int patchX, int patchY,
210 int patchW, int patchH,
211 MuPDFCore.Cookie cookie) {
212 updatePageInternal(bm, page, pageW, pageH, patchX, patchY, patchW, patchH, cookie.cookiePtr);
215 public synchronized PassClickResult passClickEvent(int page, float x, float y) {
216 boolean changed = passClickEventInternal(page, x, y) != 0;
218 switch (WidgetType.values()[getFocusedWidgetTypeInternal()])
221 return new PassClickResultText(changed, getFocusedWidgetTextInternal());
224 return new PassClickResultChoice(changed, getFocusedWidgetChoiceOptions(), getFocusedWidgetChoiceSelected());
226 return new PassClickResultSignature(changed, getFocusedWidgetSignatureState());
228 return new PassClickResult(changed);
233 public synchronized boolean setFocusedWidgetText(int page, String text) {
236 success = setFocusedWidgetTextInternal(text) != 0 ? true : false;
241 public synchronized void setFocusedWidgetChoiceSelected(String [] selected) {
242 setFocusedWidgetChoiceSelectedInternal(selected);
245 public synchronized String checkFocusedSignature() {
246 return checkFocusedSignatureInternal();
249 public synchronized boolean signFocusedSignature(String keyFile, String password) {
250 return signFocusedSignatureInternal(keyFile, password);
253 public synchronized LinkInfo [] getPageLinks(int page) {
254 return getPageLinksInternal(page);
257 public synchronized RectF [] getWidgetAreas(int page) {
258 return getWidgetAreasInternal(page);
261 public synchronized Annotation [] getAnnoations(int page) {
262 return getAnnotationsInternal(page);
265 public synchronized RectF [] searchPage(int page, String text) {
267 return searchPage(text);
270 public synchronized byte[] html(int page) {
275 public synchronized TextWord [][] textLines(int page) {
277 TextChar[][][][] chars = text();
279 // The text of the page held in a hierarchy (blocks, lines, spans).
280 // Currently we don't need to distinguish the blocks level or
281 // the spans, and we need to collect the text into words.
282 ArrayList<TextWord[]> lns = new ArrayList<TextWord[]>();
284 for (TextChar[][][] bl: chars) {
287 for (TextChar[][] ln: bl) {
288 ArrayList<TextWord> wds = new ArrayList<TextWord>();
289 TextWord wd = new TextWord();
291 for (TextChar[] sp: ln) {
292 for (TextChar tc: sp) {
295 } else if (wd.w.length() > 0) {
302 if (wd.w.length() > 0)
306 lns.add(wds.toArray(new TextWord[wds.size()]));
310 return lns.toArray(new TextWord[lns.size()][]);
313 public synchronized void addMarkupAnnotation(int page, PointF[] quadPoints, Annotation.Type type) {
315 addMarkupAnnotationInternal(quadPoints, type.ordinal());
318 public synchronized void addInkAnnotation(int page, PointF[][] arcs) {
320 addInkAnnotationInternal(arcs);
323 public synchronized void deleteAnnotation(int page, int annot_index) {
325 deleteAnnotationInternal(annot_index);
328 public synchronized boolean hasOutline() {
329 return hasOutlineInternal();
332 public synchronized OutlineItem [] getOutline() {
333 return getOutlineInternal();
336 public synchronized boolean needsPassword() {
337 return needsPasswordInternal();
340 public synchronized boolean authenticatePassword(String password) {
341 return authenticatePasswordInternal(password);
344 public synchronized boolean hasChanges() {
345 return hasChangesInternal();
348 public synchronized void save() {