1 package org.coolreader.crengine; 2 3 4 import android.graphics.Bitmap; 5 6 import java.io.ByteArrayOutputStream; 7 import java.io.IOException; 8 import java.io.InputStream; 9 10 public class DocView { 11 12 public static final Logger log = L.create("dv"); 13 14 public static final int SWAP_DONE = 0; 15 public static final int SWAP_TIMEOUT = 1; 16 public static final int SWAP_ERROR = 2; 17 18 private final Object mutex; 19 DocView(Object mutex)20 public DocView(Object mutex) { 21 log.i("DocView()"); 22 this.mutex = mutex; 23 } 24 25 /** 26 * Create native object. 27 */ create()28 public void create() { 29 synchronized(mutex) { 30 createInternal(); 31 } 32 } 33 34 /** 35 * Destroy native object. 36 */ destroy()37 public void destroy() { 38 synchronized(mutex) { 39 destroyInternal(); 40 } 41 } 42 43 /** 44 * Set document callback. 45 * @param readerCallback is callback to set 46 */ setReaderCallback(ReaderCallback readerCallback)47 public void setReaderCallback(ReaderCallback readerCallback) { 48 this.readerCallback = readerCallback; 49 } 50 51 /** 52 * If document uses cache file, swap all unsaved data to it. 53 * @return either SWAP_DONE, SWAP_TIMEOUT, SWAP_ERROR 54 */ swapToCache()55 public int swapToCache() { 56 57 synchronized(mutex) { 58 return swapToCacheInternal(); 59 } 60 } 61 62 /** 63 * Follow link. 64 * @param link 65 * @return 66 */ goLink(String link)67 public int goLink(String link) { 68 synchronized(mutex) { 69 return goLinkInternal(link); 70 } 71 } 72 73 /** 74 * Find a link near to specified window coordinates. 75 * @param x 76 * @param y 77 * @param delta 78 * @return 79 */ checkLink(int x, int y, int delta)80 public String checkLink(int x, int y, int delta) { 81 synchronized(mutex) { 82 return checkLinkInternal(x, y, delta); 83 } 84 } 85 86 /** 87 * Set selection range. 88 * @param sel 89 */ updateSelection(Selection sel)90 public void updateSelection(Selection sel) { 91 synchronized(mutex) { 92 updateSelectionInternal(sel); 93 } 94 } 95 96 /** 97 * Move selection. 98 * @param sel 99 * @param moveCmd 100 * @param params 101 * @return 102 */ moveSelection(Selection sel, int moveCmd, int params)103 public boolean moveSelection(Selection sel, 104 int moveCmd, int params) { 105 synchronized(mutex) { 106 return moveSelectionInternal(sel, moveCmd, params); 107 } 108 } 109 110 /** 111 * Send battery state to native object. 112 * @param state 113 */ setBatteryState(int state)114 public void setBatteryState(int state) { 115 synchronized(mutex) { 116 setBatteryStateInternal(state); 117 } 118 } 119 120 /** 121 * Get current book coverpage data bytes. 122 * @return 123 */ getCoverPageData()124 public byte[] getCoverPageData() { 125 synchronized(mutex) { 126 return getCoverPageDataInternal(); 127 } 128 } 129 130 /** 131 * Set texture for page background. 132 * @param imageBytes 133 * @param tileFlags 134 */ setPageBackgroundTexture( byte[] imageBytes, int tileFlags)135 public void setPageBackgroundTexture( 136 byte[] imageBytes, int tileFlags) { 137 synchronized(mutex) { 138 setPageBackgroundTextureInternal(imageBytes, tileFlags); 139 } 140 } 141 142 /** 143 * create empty document with specified message (e.g. to show errors) 144 * @param title 145 * @param message 146 * @return 147 */ createDefaultDocument(String title, String message)148 public void createDefaultDocument(String title, String message) 149 { 150 synchronized(mutex) { 151 createDefaultDocumentInternal(title, message); 152 } 153 } 154 155 /** 156 * Load document from file. 157 * @param fileName 158 * @return 159 */ loadDocument(String fileName)160 public boolean loadDocument(String fileName) { 161 synchronized(mutex) { 162 return loadDocumentInternal(fileName); 163 } 164 } 165 166 /** 167 * Load document from input stream. 168 * @param inputStream 169 * @param contentPath 170 * @return 171 */ loadDocumentFromStream(InputStream inputStream, String contentPath)172 public boolean loadDocumentFromStream(InputStream inputStream, String contentPath) { 173 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 174 int errorCode = 0; 175 try { 176 byte [] buf = new byte [4096]; 177 int readBytes; 178 while (true) { 179 readBytes = inputStream.read(buf); 180 if (readBytes > 0) 181 outputStream.write(buf, 0, readBytes); 182 else 183 break; 184 } 185 } catch (IOException e1) { 186 errorCode = 1; 187 } catch (OutOfMemoryError e2) { 188 errorCode = 2; 189 } 190 if (0 == errorCode) { 191 synchronized (mutex) { 192 return loadDocumentFromMemoryInternal(outputStream.toByteArray(), contentPath); 193 } 194 } 195 // TODO: pass error code to caller to show message for user. 196 return false; 197 } 198 199 /** 200 * Get settings from native object. 201 * @return 202 */ getSettings()203 public java.util.Properties getSettings() { 204 synchronized(mutex) { 205 return getSettingsInternal(); 206 } 207 } 208 209 /** 210 * Apply settings. 211 * @param settings 212 * @return 213 */ applySettings(java.util.Properties settings)214 public boolean applySettings(java.util.Properties settings) { 215 synchronized(mutex) { 216 return applySettingsInternal(settings); 217 } 218 } 219 getDocProps()220 public java.util.Properties getDocProps() { 221 synchronized (mutex) { 222 return getDocPropsInternal(); 223 } 224 } 225 226 /** 227 * Set stylesheet for document. 228 * @param stylesheet 229 */ setStylesheet(String stylesheet)230 public void setStylesheet(String stylesheet) { 231 synchronized(mutex) { 232 setStylesheetInternal(stylesheet); 233 } 234 } 235 requestRender()236 public void requestRender() { 237 doCommand(ReaderCommand.DCMD_REQUEST_RENDER.getNativeId(), 0); 238 } 239 240 /** 241 * Change window size. 242 * @param dx 243 * @param dy 244 */ resize(int dx, int dy)245 public void resize(int dx, int dy) { 246 synchronized(mutex) { 247 log.d("DocView.resize(" + dx + ", "+ dy + ")"); 248 resizeInternal(dx, dy); 249 } 250 } 251 252 /** 253 * Execute command by native object. 254 * @param command 255 * @param param 256 * @return 257 */ doCommand(int command, int param)258 public boolean doCommand(int command, int param) { 259 synchronized(mutex) { 260 return doCommandInternal(command, param); 261 } 262 } 263 264 /** 265 * Get current page bookmark info. 266 * @return 267 */ getCurrentPageBookmark()268 public Bookmark getCurrentPageBookmark() { 269 synchronized(mutex) { 270 return getCurrentPageBookmarkInternal(); 271 } 272 } 273 274 /** 275 * Get current page bookmark info, returning null if document is not yet rendered (to avoid long call). 276 * @return bookmark for current page, null if cannot be determined fast 277 */ getCurrentPageBookmarkNoRender()278 public Bookmark getCurrentPageBookmarkNoRender() { 279 if (!isRenderedInternal()) 280 return null; 281 synchronized(mutex) { 282 return getCurrentPageBookmarkInternal(); 283 } 284 } 285 286 /** 287 * Check whether document is formatted/rendered. 288 * @return true if document is rendered, and e.g. retrieving of page image will not cause long activity (formatting etc.) 289 */ isRendered()290 public boolean isRendered() { 291 // thread safe 292 return isRenderedInternal(); 293 } 294 295 /** 296 * Move reading position to specified xPath. 297 * @param xPath 298 * @return 299 */ goToPosition(String xPath, boolean saveToHistory)300 public boolean goToPosition(String xPath, boolean saveToHistory) { 301 synchronized(mutex) { 302 return goToPositionInternal(xPath, saveToHistory); 303 } 304 } 305 306 /** 307 * Get position properties by xPath. 308 * @param xPath 309 * @return 310 */ getPositionProps(String xPath, boolean precise)311 public PositionProperties getPositionProps(String xPath, boolean precise) { 312 synchronized(mutex) { 313 return getPositionPropsInternal(xPath, precise); 314 } 315 } 316 317 /** 318 * Fill book info fields using metadata from current book. 319 * @param info 320 */ updateBookInfo(BookInfo info)321 public void updateBookInfo(BookInfo info) { 322 synchronized(mutex) { 323 updateBookInfoInternal(info); 324 } 325 } 326 327 /** 328 * Get TOC tree from current book. 329 * @return 330 */ getTOC()331 public TOCItem getTOC() { 332 synchronized(mutex) { 333 return getTOCInternal(); 334 } 335 } 336 337 /** 338 * Clear selection. 339 */ clearSelection()340 public void clearSelection() { 341 synchronized(mutex) { 342 clearSelectionInternal(); 343 } 344 } 345 346 /** 347 * Find text in book. 348 * @param pattern 349 * @param origin 350 * @param reverse 351 * @param caseInsensitive 352 * @return 353 */ findText(String pattern, int origin, int reverse, int caseInsensitive)354 public boolean findText(String pattern, int origin, 355 int reverse, int caseInsensitive) { 356 synchronized(mutex) { 357 return findTextInternal(pattern, origin, reverse, caseInsensitive); 358 } 359 } 360 361 /** 362 * Get current page image. 363 * @param bitmap is buffer to put data to. 364 */ getPageImage(Bitmap bitmap)365 public void getPageImage(Bitmap bitmap) { 366 synchronized(mutex) { 367 getPageImageInternal(bitmap, DeviceInfo.EINK_SCREEN ? 4 : 32); 368 } 369 } 370 371 /** 372 * Check whether point of current document contains image. 373 * If image is found, image becomes current image to be drawn by drawImage(), dstImage fields are set to image dimension. 374 * 375 * @param x is X coordinate in document window 376 * @param y is Y coordinate in document window 377 * @param dstImage is to place found image dimensions to 378 * @return true if point belongs to image 379 */ checkImage(int x, int y, ImageInfo dstImage)380 public boolean checkImage(int x, int y, ImageInfo dstImage) { 381 synchronized(mutex) { 382 return checkImageInternal(x, y, dstImage); 383 } 384 } 385 386 /** 387 * Check whether point of current document belongs to bookmark. 388 * 389 * @param x is X coordinate in document window 390 * @param y is Y coordinate in document window 391 * @return bookmark if point belongs to bookmark, null otherwise 392 */ checkBookmark(int x, int y)393 public Bookmark checkBookmark(int x, int y) { 394 synchronized(mutex) { 395 Bookmark dstBookmark = new Bookmark(); 396 if (checkBookmarkInternal(x, y, dstBookmark)) { 397 return dstBookmark; 398 } 399 return null; 400 } 401 } 402 403 404 /** 405 * Draws currently opened image to bitmap. 406 * @param bitmap is destination bitmap 407 * @param imageInfo contains image position and scaling parameters. 408 * @return true if current image is drawn successfully. 409 */ drawImage(Bitmap bitmap, ImageInfo imageInfo)410 public boolean drawImage(Bitmap bitmap, ImageInfo imageInfo) { 411 synchronized(mutex) { 412 return drawImageInternal(bitmap, DeviceInfo.EINK_SCREEN ? 4 : 32, imageInfo); 413 } 414 } 415 416 /** 417 * Close currently opened image, free resources. 418 * @return true if there was opened current image, and it's now closed 419 */ closeImage()420 public boolean closeImage() { 421 synchronized(mutex) { 422 return closeImageInternal(); 423 } 424 } 425 426 /** 427 * Highlight bookmarks. 428 * Remove highlight using clearSelection(). 429 * @params bookmarks is array of bookmarks to highlight 430 */ hilightBookmarks(Bookmark[] bookmarks)431 public void hilightBookmarks(Bookmark[] bookmarks) { 432 synchronized(mutex) { 433 hilightBookmarksInternal(bookmarks); 434 } 435 } 436 437 //======================================================================================== 438 // Native functions 439 /* implementend by libcr3engine.so */ 440 //======================================================================================== getPageImageInternal(Bitmap bitmap, int bpp)441 private native void getPageImageInternal(Bitmap bitmap, int bpp); 442 createInternal()443 private native void createInternal(); 444 destroyInternal()445 private native void destroyInternal(); 446 createDefaultDocumentInternal(String title, String message)447 private native void createDefaultDocumentInternal(String title, String message); 448 loadDocumentInternal(String fileName)449 private native boolean loadDocumentInternal(String fileName); 450 loadDocumentFromMemoryInternal(byte [] buf, String contentPath)451 private native boolean loadDocumentFromMemoryInternal(byte [] buf, String contentPath); 452 getSettingsInternal()453 private native java.util.Properties getSettingsInternal(); 454 applySettingsInternal( java.util.Properties settings)455 private native boolean applySettingsInternal( 456 java.util.Properties settings); 457 getDocPropsInternal()458 private native java.util.Properties getDocPropsInternal(); 459 setStylesheetInternal(String stylesheet)460 private native void setStylesheetInternal(String stylesheet); 461 resizeInternal(int dx, int dy)462 private native void resizeInternal(int dx, int dy); 463 doCommandInternal(int command, int param)464 private native boolean doCommandInternal(int command, int param); 465 getCurrentPageBookmarkInternal()466 private native Bookmark getCurrentPageBookmarkInternal(); 467 goToPositionInternal(String xPath, boolean saveToHistory)468 private native boolean goToPositionInternal(String xPath, boolean saveToHistory); 469 getPositionPropsInternal(String xPath, boolean precise)470 private native PositionProperties getPositionPropsInternal(String xPath, boolean precise); 471 updateBookInfoInternal(BookInfo info)472 private native void updateBookInfoInternal(BookInfo info); 473 getTOCInternal()474 private native TOCItem getTOCInternal(); 475 clearSelectionInternal()476 private native void clearSelectionInternal(); 477 findTextInternal(String pattern, int origin, int reverse, int caseInsensitive)478 private native boolean findTextInternal(String pattern, int origin, 479 int reverse, int caseInsensitive); 480 setBatteryStateInternal(int state)481 private native void setBatteryStateInternal(int state); 482 getCoverPageDataInternal()483 private native byte[] getCoverPageDataInternal(); 484 setPageBackgroundTextureInternal( byte[] imageBytes, int tileFlags)485 private native void setPageBackgroundTextureInternal( 486 byte[] imageBytes, int tileFlags); 487 updateSelectionInternal(Selection sel)488 private native void updateSelectionInternal(Selection sel); 489 moveSelectionInternal(Selection sel, int moveCmd, int params)490 private native boolean moveSelectionInternal(Selection sel, 491 int moveCmd, int params); 492 checkLinkInternal(int x, int y, int delta)493 private native String checkLinkInternal(int x, int y, int delta); 494 checkImageInternal(int x, int y, ImageInfo dstImage)495 private native boolean checkImageInternal(int x, int y, ImageInfo dstImage); 496 checkBookmarkInternal(int x, int y, Bookmark dstBookmark)497 private native boolean checkBookmarkInternal(int x, int y, Bookmark dstBookmark); 498 drawImageInternal(Bitmap bitmap, int bpp, ImageInfo dstImage)499 private native boolean drawImageInternal(Bitmap bitmap, int bpp, ImageInfo dstImage); 500 closeImageInternal()501 private native boolean closeImageInternal(); 502 isRenderedInternal()503 private native boolean isRenderedInternal(); 504 goLinkInternal(String link)505 private native int goLinkInternal(String link); 506 hilightBookmarksInternal(Bookmark[] bookmarks)507 private native void hilightBookmarksInternal(Bookmark[] bookmarks); 508 509 // / returns either SWAP_DONE, SWAP_TIMEOUT or SWAP_ERROR swapToCacheInternal()510 private native int swapToCacheInternal(); 511 512 private long mNativeObject; // used from JNI 513 514 private ReaderCallback readerCallback; // used from JNI 515 516 517 } 518