/** * @file FbreaderAdapter.java * * @revision: none * * @version 0.0.01 * @author: Zenki (zhajun), zenki2001cn@163.com * @date: 2011-4-27 下午01:37:24 */ package com.easyview.ebook.reader.engine.core.fbreader; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; import java.nio.charset.CodingErrorAction; import java.util.List; import org.geometerplus.android.fbreader.library.SQLiteBooksDatabase; import org.geometerplus.fbreader.bookmodel.TOCTree; import org.geometerplus.fbreader.fbreader.ActionCode; import org.geometerplus.fbreader.fbreader.FBReaderApp; import org.geometerplus.fbreader.fbreader.FBView; import org.geometerplus.fbreader.library.Author; import org.geometerplus.fbreader.library.Book; import org.geometerplus.fbreader.library.Library; import org.geometerplus.zlibrary.core.filesystem.ZLFile; import org.geometerplus.zlibrary.core.image.ZLImage; import org.geometerplus.zlibrary.core.options.ZLIntegerRangeOption; import org.geometerplus.zlibrary.core.sqliteconfig.ZLSQLiteConfig; import org.geometerplus.zlibrary.core.view.ZLView; import org.geometerplus.zlibrary.text.model.ZLTextMark; import org.geometerplus.zlibrary.text.model.ZLTextModel; import org.geometerplus.zlibrary.text.view.ZLTextElement; import org.geometerplus.zlibrary.text.view.ZLTextParagraphCursor; import org.geometerplus.zlibrary.text.view.ZLTextPosition; import org.geometerplus.zlibrary.text.view.ZLTextView; import org.geometerplus.zlibrary.text.view.ZLTextWord; import org.geometerplus.zlibrary.text.view.ZLTextWordCursor; import org.geometerplus.zlibrary.text.view.style.ZLTextStyleCollection; import org.geometerplus.zlibrary.ui.android.image.ZLAndroidImageManager; import org.geometerplus.zlibrary.ui.android.library.ZLAndroidLibrary; import org.geometerplus.zlibrary.ui.android.view.BitmapManager; import android.graphics.Bitmap; import com.easyview.ebook.reader.engine.core.DecAdapter; import com.easyview.ebook.reader.engine.core.ERManager; import com.easyview.ebook.reader.engine.core.EngineCode; import com.easyview.ebook.reader.engine.core.IEngineService; import com.easyview.ebook.reader.engine.core.EngineCode.EngineMsgCode; import com.easyview.ebook.reader.engine.core.EngineCode.FbreaderMsgCode; import com.easyview.ebook.reader.engine.model.BookSearchInfo; import com.easyview.ebook.reader.engine.model.BookSearchInfo.BookSearchResult; import com.easyview.ebook.reader.engine.util.Logger; /** * */ public class FbreaderAdapter extends DecAdapter { static private final String TAG = "FbreaderAdapter"; private static FbreaderAdapter mFbreaderAdapter; private static EngineCode mEngineCode; private IEngineService mIes; private ZLFile mZlfile; private FBReaderApp mZlApplication; private BitmapManager mBitmapManager; private ZLSQLiteConfig mZlSqlConfig; private SQLiteBooksDatabase mSqlBooksDb; private Book mFBook; private int mViewWidth = 0; private int mViewHeight = 0; private Bitmap.Config mBitmapConfig = Bitmap.Config.RGB_565; private int[] mChapterIndexs; private String[] mChapterTitles; private int SUMMARY_MAX_NUM = 50; public static final String LOCATION_PREFIX_HEADER = "#fbloc"; public static final String LOCATION_PREFIX = LOCATION_PREFIX_HEADER + "(%d,%d,%d)"; protected enum PageType { PreviousPage, CurrentPage, NextPage } protected static FbreaderAdapter getInstance() { if (null == mFbreaderAdapter) { mFbreaderAdapter = new FbreaderAdapter(); mEngineCode = EngineCode.getInstance(); } return mFbreaderAdapter; } private FbreaderAdapter() { initFbreader(); } @Override protected void cancelProcessing() { Logger.dLog(TAG, "cancelProcessing"); } @Override protected void free() { resetCache(); if (mFbreaderAdapter != null) { mFbreaderAdapter = null; } if (mEngineCode != null) { mEngineCode.free(); mEngineCode = null; } if (mBitmapManager != null) { mBitmapManager = null; } if (mZlApplication != null) { mZlApplication = null; } if (mZlSqlConfig != null) { mZlSqlConfig.closeDatabase(); mZlSqlConfig = null; } if (mIes != null) { mIes = null; } Logger.vLog(TAG, "AdobeAdapter free adapter: " + mFbreaderAdapter + " errorCode: " + mEngineCode); } protected int openFile(String url) { Logger.vLog(TAG, "openFile enter>>>"); int code = EngineCode.EngineMsgCode.NO_ERROR; // step 1: create zlfile. mZlfile = ZLFile.createFileByPath(url); if (mZlfile != null) { // step 2: create zlapplication. mZlApplication = createApplication(mZlfile); if (mZlApplication != null) { // step 3: open file. mZlApplication.openFile(mZlfile); mFBook = mZlApplication.Model.Book; // step 4: reset view resetBitmap(); // step 5: computer text size computerTextSize(); } else { code = EngineCode.FbreaderMsgCode.STATE_ERROR_OPEN_FILE_FAILED; } } else { code = EngineCode.FbreaderMsgCode.STATE_ERROR_OPEN_FILE_FAILED; } mEngineCode.setLastCode(code); Logger.vLog(TAG, "openFile exit>>>"); return code; } protected int closeFile() { Logger.vLog(TAG, "closeFile enter>>>"); int code = 0; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; } else { mFBook.storePosition(mZlApplication.BookTextView.getStartCursor()); mZlApplication.doAction(ActionCode.EXIT); resetCache(); } Logger.vLog(TAG, "closeFile exit."); return code; } protected void setViewPortSize(int w, int h) { Logger.vLog(TAG, "setViewportSize enter>>> width = " + w + " height = " + h); mViewWidth = w; mViewHeight = h; mBitmapManager.setSize(w, h); Logger.vLog(TAG, "setViewportSize exit."); } protected Bitmap getBitmap(PageType pageType) { resetBitmap(); Bitmap bmp = null; if (pageType == PageType.CurrentPage) { bmp = mBitmapManager.getBitmap(ZLView.PageIndex.current, mViewWidth, mViewHeight); } else if (pageType == PageType.PreviousPage) { bmp = mBitmapManager.getBitmap(ZLView.PageIndex.previous, mViewWidth, mViewHeight); } else if (pageType == PageType.NextPage) { bmp = mBitmapManager.getBitmap(ZLView.PageIndex.next, mViewWidth, mViewHeight); } else { bmp = mBitmapManager.getBitmap(ZLView.PageIndex.current, mViewWidth, mViewHeight); } if (null == bmp) { mEngineCode .setLastCode(EngineMsgCode.STATE_ERROR_GET_BITMAP_FAILED); Logger.eLog(TAG, "getBitmap == null"); } else { mEngineCode.setLastCode(EngineMsgCode.NO_ERROR); } return bmp; } protected void resetBitmap() { if (mBitmapManager != null) { mBitmapManager.reset(); } } protected int getTotalPageNum() { Logger.vLog(TAG, "getTotalPageNum enter>>>"); int totalpageNum = 1; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { mEngineCode .setLastCode(EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR); } else { totalpageNum = view.computePageNumber(); // if (totalpageNum > 1) { // totalpageNum--; // } } Logger.vLog(TAG, "getTotalPageNum exit>>>"); return totalpageNum; } protected int getCurrentPageNum() { Logger.vLog(TAG, "getCurrentPageNum enter>>>"); int curPageNum = 1; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { mEngineCode .setLastCode(EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR); } else { curPageNum = view.computeCurrentPage(); Logger.eLog(TAG, "curPageNum = " + curPageNum); // if (curPageIndex > 0) { // curPageIndex--; // } } Logger.vLog(TAG, "getCurrentPageNum exit>>>"); return curPageNum; } protected String getCoverUri() { ZLImage image = Library.getCover(mZlfile); if (image != null) { return image.getURI(); } else { return "null"; } } protected String getAuthor() { Logger.vLog(TAG, "getAuthor enter>>>"); int code = EngineMsgCode.NO_ERROR; String author = "null"; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { List<Author> authors = mFBook.authors(); if (authors.size() > 1) { author = authors.get(0).DisplayName; } } Logger.vLog(TAG, "getAuthor exit."); return author; } protected String getTitle() { Logger.vLog(TAG, "getTitle enter>>>"); int code = EngineMsgCode.NO_ERROR; String title = "null"; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { String encoding = mFBook.getEncoding(); String temp; title = mFBook.getTitle(); if (encoding != null) { temp = convertString(title, encoding, "UTF-8"); if (temp != null) { title = temp; } } // title = mFBook.getTitle(); } Logger.vLog(TAG, "getTitle exit."); return title; } protected String getEncoding() { Logger.vLog(TAG, "getEncoding enter>>>"); int code = EngineMsgCode.NO_ERROR; String encoding = "null"; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { encoding = mFBook.getEncoding(); } Logger.vLog(TAG, "getEncoding exit."); return encoding; } protected String getLanguage() { Logger.vLog(TAG, "getLanguage enter>>>"); int code = EngineMsgCode.NO_ERROR; String language = "null"; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { language = mFBook.getLanguage(); } Logger.vLog(TAG, "getLanguage exit."); return language; } protected int zoomIn() { Logger.vLog(TAG, "zoomIn enter>>>"); int code = 0; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { mZlApplication.doAction(ActionCode.INCREASE_FONT); resetBitmap(); computerTextSize(); code = mEngineCode.getLastCode(); } Logger.vLog(TAG, "zoomIn exit>>>"); return code; } protected int zoomOut() { Logger.vLog(TAG, "zoomOut enter>>>"); int code = 0; if (null == mZlApplication) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { mZlApplication.doAction(ActionCode.DECREASE_FONT); resetBitmap(); computerTextSize(); } Logger.vLog(TAG, "zoomOut exit>>>"); return code; } protected int getFontSize() { int fontSize; ZLIntegerRangeOption option = ZLTextStyleCollection.Instance() .getBaseStyle().FontSizeOption; fontSize = option.getValue(); return fontSize; } protected boolean pageUp() { Logger.vLog(TAG, "pageUp enter>>>"); int code = 0; if (null == mZlApplication) { code = FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { // if (!previousParagraph()) { // code = EngineCode.FbreaderMsgCode.STATE_NORMAL_BEGIN_OF_PH; // mEngineCode.setLastCode(code); // Logger.vLog(TAG, "pageUp AT BEGIN exit>>>"); // // return false; // } // nextParagraph(); if (isHomeParagraph()) { // previousParagraph(false); return false; } previousParagraph(false); } Logger.vLog(TAG, "pageUp exit>>>"); return true; } protected boolean pageDown() { Logger.vLog(TAG, "pageDown enter>>>"); int code = 0; if (null == mZlApplication) { code = FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { // if (!nextParagraph()) { // code = EngineCode.FbreaderMsgCode.STATE_NORMAL_END_OF_PH; // mEngineCode.setLastCode(code); // Logger.vLog(TAG, "pageDown AT END exit>>>"); // // return false; // } // previousParagraph(); if (isEndParagraph()) { return false; } nextParagraph(true); } Logger.vLog(TAG, "pageDown exit>>>"); return true; } protected int gotoPage(int page) { Logger.vLog(TAG, "gotoPage enter>>>"); int code = 0; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { view.gotoPage(page); } Logger.vLog(TAG, "gotoPage exit>>>"); return code; } protected int gotoHome() { Logger.vLog(TAG, "gotoHome enter>>>"); int code = 0; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { view.gotoHome(); } Logger.vLog(TAG, "gotoHome exit>>>"); return code; } protected int gotoPosition(int paragraphIndex, int wordIndex, int charIndex) { Logger.vLog(TAG, "gotoPosition enter>>>"); int code = 0; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { view.gotoPosition(paragraphIndex, wordIndex, charIndex); } Logger.vLog(TAG, "gotoPosition exit>>>"); return code; } protected int gotoPosition(ZLTextPosition postion) { Logger.vLog(TAG, "gotoPosition enter>>>"); int code = 0; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { view.gotoPosition(postion); } Logger.vLog(TAG, "gotoPosition exit>>>"); return code; } protected int gotoMark(ZLTextMark mark) { Logger.vLog(TAG, "gotoMark enter>>>"); int code = 0; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { code = EngineCode.FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { view.gotoMark(mark); } Logger.vLog(TAG, "gotoMark exit>>>"); return code; } protected boolean nextParagraph(boolean shift) { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { return false; } else { mZlApplication.doAction(ActionCode.TURN_PAGE_FORWARD); mBitmapManager.shift(shift); view.onScrollingFinished(ZLView.PageIndex.next); } return true; } protected boolean previousParagraph(boolean shift) { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { return false; } else { mZlApplication.doAction(ActionCode.TURN_PAGE_BACK); mBitmapManager.shift(shift); view.onScrollingFinished(ZLView.PageIndex.previous); } return true; } protected boolean isHeadParagraph() { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); final ZLTextWordCursor cursor = view.getStartCursor(); // Logger.vLog( // TAG, // "cursor.isNull() = " + cursor.isNull() // + " cursor.isStartOfParagraph() = " // + cursor.isStartOfParagraph() // + " cursor.getParagraphIndex() = " // + cursor.getParagraphIndex()); if (cursor.isStartOfParagraph()) { return true; } return false; } protected boolean isTailParagraph() { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); final ZLTextWordCursor cursor = view.getEndCursor(); // Logger.vLog(TAG, "cursor.isNull() = " + cursor.isNull() // + " isEndOfParagraph() = " + cursor.isEndOfParagraph() // + " cursor.getParagraphIndex() = " + cursor.getParagraphIndex()); if (cursor.isEndOfParagraph()) { return true; } return false; } protected boolean isHomeParagraph() { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); // final ZLTextWordCursor cursor = view.getStartCursor(); // Logger.vLog( // TAG, // "cursor.isNull() = " + cursor.isNull() // + " cursor.isStartOfParagraph() = " // + cursor.isStartOfParagraph() // + " cursor.getParagraphIndex() = " // + cursor.getParagraphIndex()); // if (!cursor.isNull() && cursor.isStartOfParagraph() // && cursor.getParagraphIndex() == 0) { // // Logger.vLog(TAG, "pageUp AT BEGIN exit>>>"); // return true; // } ZLView.PageIndex pageIndex = FBView.PageIndex.previous; if ((pageIndex == ZLView.PageIndex.current) || !view.canScroll(pageIndex)) { return true; } return false; } protected boolean isEndParagraph() { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); // final ZLTextWordCursor cursor = view.getStartCursor(); // ZLTextModel myModel = view.getModel(); // int curParagraphIndex = cursor.getParagraphIndex(); // // // Logger.vLog( // // TAG, // // "cursor.isNull() = " + cursor.isNull() // // + " cursor.isStartOfParagraph() = " // // + cursor.isStartOfParagraph() // // + " cursor.getParagraphIndex() = " // // + cursor.getParagraphIndex()); // if (null == myModel) { // return false; // } // // int paragraphIndex = myModel.findParagraphByTextLength(mTextSize); // // // Logger.vLog(TAG, "isEndParagraph paragraphIndex = " + // // paragraphIndex); // // if (paragraphIndex == curParagraphIndex) { // Logger.vLog(TAG, "pageDown AT END exit>>>"); // return true; // } ZLView.PageIndex pageIndex = FBView.PageIndex.next; if ((pageIndex == ZLView.PageIndex.current) || !view.canScroll(pageIndex)) { return true; } return false; } // private final HashSet<ZLTree<?>> myOpenItems = new HashSet<ZLTree<?>>(); // private ZLTree<?>[] myItems; protected String[] getChapterTitles() { Logger.vLog(TAG, "getChapterList enter>>>"); int chapters = getChapterNumber(); if (chapters < 1) { Logger.vLog(TAG, "getChapterList chapter is empty>>>"); return null; } else if (mChapterTitles != null) { Logger.vLog(TAG, "getChapterList chapter alredy loaded>>>"); return mChapterTitles; } final TOCTree root = mZlApplication.Model.TOCTree; mChapterTitles = new String[chapters]; mChapterIndexs = new int[chapters]; int id = 0; for (TOCTree tree : root) { final TOCTree.Reference reference = tree.getReference(); if (reference == null) { continue; } mChapterTitles[id] = tree.getText(); mChapterIndexs[id] = reference.ParagraphIndex; id++; // Logger.dLog(TAG, "tree.getText() = " + tree.getText() // + " reference.ParagraphIndex = " + reference.ParagraphIndex // + " reference.Model.getParagraphsNumber() = " // + reference.Model.getParagraphsNumber() // + " root.getSize() = " + root.getSize()); } Logger.vLog(TAG, "getChapterList exit>>>"); return mChapterTitles; } protected int[] getChapterIndexs() { Logger.vLog(TAG, "getChapterIndexs enter>>>"); Logger.vLog(TAG, "getChapterIndexs exit>>>"); return mChapterIndexs; } protected int getChapterNumber() { Logger.vLog(TAG, "getChapterNumber enter>>>"); int num = -1; final TOCTree root = mZlApplication.Model.TOCTree; if (null == root) { } else { num = root.getSize() - 1; } Logger.vLog(TAG, "getChapterNumber exit>>>"); return num; } protected int goToChapterByTitle(String title) { Logger.vLog(TAG, "goToChapter enter>>>"); int index = searchChapter(title); if (!mEngineCode.noError(index)) { mEngineCode.setLastCode(index); } else { gotoPosition(index, 0, 0); mEngineCode.setLastCode(EngineMsgCode.NO_ERROR); } Logger.vLog(TAG, "goToChapter exit."); return index; } protected int goToChapterByIndex(int id) { Logger.vLog(TAG, "goToChapterIndex enter>>>"); int code = gotoPosition(mChapterIndexs[id], 0, 0); Logger.vLog(TAG, "goToChapterIndex exit."); return code; } protected int goToChapterByParagraphIndex(int paragraphIndex) { Logger.vLog(TAG, "goToChapterByParagraphIndex enter>>>"); int code = gotoPosition(paragraphIndex, 0, 0); Logger.vLog(TAG, "goToChapterByParagraphIndex exit."); return code; } protected int getCurrentChapterIndex() { Logger.vLog(TAG, "getCurrentChapterIndex enter>>>"); int index = EngineMsgCode.ENGINE_WARN_CHAPTER_INDEX_FAILED; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { mEngineCode.setLastCode(index); } else { index = searchChapter(view.getStartCursor().getParagraphIndex()); } Logger.vLog(TAG, "getCurrentChapterIndex exit>>>" + " index = " + index); return index; } protected int getCurrentParagraphIndex() { Logger.vLog(TAG, "getCurrentParagraphIndex enter>>>"); int index = FbreaderMsgCode.STATE_ERROR_PH_INDEX_ERROR; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); if (null == view) { mEngineCode.setLastCode(index); } else { index = view.getEndCursor().getParagraphIndex(); } Logger.vLog(TAG, "getCurrentParagraphIndex exit>>>" + " index = " + index); return index; } protected String getLocation() { String location = "null"; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); final ZLTextWordCursor cursor = view.getStartCursor(); int pi = cursor.getParagraphIndex(); int wi = cursor.getElementIndex(); int ci = cursor.getCharIndex(); location = String.format(LOCATION_PREFIX, pi, wi, ci); return location; } protected String getLocation(int pi, int wi, int ci) { String location = "null"; location = String.format(LOCATION_PREFIX, pi, wi, ci); return location; } protected int[] parseLocation(String location) { Logger.vLog(TAG, "parseLocation enter>>> location = " + location); int[] indexs = { -1, -1, -1 }; try { if (location.startsWith(LOCATION_PREFIX_HEADER)) { String[] temp = location.substring( LOCATION_PREFIX_HEADER.length() + 1, location.length() - 1).split(","); indexs[0] = Integer.valueOf(temp[0]); indexs[1] = Integer.valueOf(temp[1]); indexs[2] = Integer.valueOf(temp[2]); } } catch (Exception e) { Logger.vLog(TAG, "e =>>>" + e); } Logger.vLog(TAG, "parseLocation exit>>>"); return indexs; } // search part begin protected int startSearch(String keyword) { Logger.vLog(TAG, "getSearchResult enter>>>"); int code = 0; if (null == mZlApplication) { } else { mZlApplication.TextSearchPatternOption.setValue(keyword); code = mZlApplication.getTextView().search(keyword, true, false, false, false); } Logger.vLog(TAG, "getSearchResult exit."); return code; } protected int searchNext() { Logger.vLog(TAG, "searchNext enter>>>"); int code = 0; if (null == mZlApplication) { code = FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; } else { if (!mZlApplication.isActionEnabled(ActionCode.FIND_NEXT)) { code = EngineMsgCode.ENGINE_ERROR_SEARCH_GO_NEXT_FAILED; } else { mZlApplication.doAction(ActionCode.FIND_NEXT); } } Logger.vLog(TAG, "searchNext exit."); return code; } protected int searchPrevious() { Logger.vLog(TAG, "searchPrevious enter>>>"); int code = 0; if (null == mZlApplication) { code = FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; } else { if (!mZlApplication.isActionEnabled(ActionCode.FIND_PREVIOUS)) { code = EngineMsgCode.ENGINE_ERROR_SEARCH_GO_PREVIOUS_FAILED; } else { mZlApplication.doAction(ActionCode.FIND_PREVIOUS); } } Logger.vLog(TAG, "searchPrevious exit."); return code; } protected BookSearchInfo.BookSearchResult[] getSearchResult() { Logger.vLog(TAG, "getSearchResult enter>>>"); BookSearchInfo.BookSearchResult[] results = null; List<ZLTextMark> marks; ZLTextMark tempMark; IEngineService ies = (IEngineService) ERManager.getService(ERManager.ERENGINE_SERVICE); com.easyview.ebook.reader.engine.model.Book book = ies.getBook(); int code = 0; if (null == mZlApplication) { code = FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; mEngineCode.setLastCode(code); } else { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); ZLTextModel model = view.getModel(); if (!view.findResultsAreEmpty()) { marks = model.getMarks(); results = book.makeSearchResults(marks.size()); for (int i = 0; i < results.length; i++) { tempMark = marks.get(i); if (null == results[i]) { results[i] = book.makeSearchResult(); } convertMarkToSearchResult(tempMark, results[i]); } } } Logger.vLog(TAG, "getSearchResult exit."); return results; } protected int quitSearch() { Logger.vLog(TAG, "quitSearch enter>>>"); int code = 0; if (null == mZlApplication) { return FbreaderMsgCode.STATE_ERROR_APP_INIT_ERROR; } else { mZlApplication.doAction(ActionCode.CLEAR_FIND_RESULTS); } Logger.vLog(TAG, "quitSearch exit."); return code; } protected String getSummary() { Logger.vLog(TAG, "getSummary enter>>>"); String summary = ""; if (null == mZlApplication) { } else { final ZLTextView view = (ZLTextView) mZlApplication .getCurrentView(); final ZLTextWordCursor cursor = view.getStartCursor(); summary = getBookmarkText(cursor, SUMMARY_MAX_NUM); } Logger.vLog(TAG, "getSummary exit."); return summary.trim().replace("\n", " "); } protected void openLinkByTouch(int x, int y) { Logger.vLog(TAG, "openLinkByTouch enter>>>"); final ZLView view = mZlApplication.getCurrentView(); view.onFingerSingleTap(x, y); Logger.vLog(TAG, "openLinkByTouch exit."); } protected void startHighlightByXY(int x, int y) { Logger.vLog(TAG, "startHighlightByXY enter>>>"); final FBView view = (FBView) mZlApplication.getCurrentView(); // view.onFingerPress(x, y); view.onFingerLongPress(x, y); Logger.vLog(TAG, "startHighlightByXY exit."); } protected void moveHighlightByXY(int x, int y) { Logger.vLog(TAG, "moveHighlightByXY enter>>>"); final FBView view = (FBView) mZlApplication.getCurrentView(); view.onFingerMove(x, y); Logger.vLog(TAG, "moveHighlightByXY exit."); } protected void endHighlightByXY(int x, int y) { Logger.vLog(TAG, "endHighlightByXY enter>>>"); final FBView view = (FBView) mZlApplication.getCurrentView(); view.onFingerRelease(x, y); Logger.vLog(TAG, "endHighlightByXY exit."); } protected String getSelectedText() { Logger.vLog(TAG, "getSelectedText enter>>>"); final FBView view = (FBView) mZlApplication.getCurrentView(); String selStr = view.getSelectedText(); Logger.dLog(TAG, "iEndHighlightByXY selStr = " + selStr); Logger.vLog(TAG, "getSelectedText exit."); return selStr; } protected String getHighlightStartLoc() { Logger.vLog(TAG, "getHighlightStartLoc enter>>>"); String loc = com.easyview.ebook.reader.engine.model.Book.VALUE_NULL; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); ZLTextPosition position = view.getSelectionStartPosition(); if (null == position) { return loc; } int pi = position.getParagraphIndex(); int wi = position.getElementIndex(); int ci = position.getCharIndex(); loc = String.format(LOCATION_PREFIX, pi, wi, ci); Logger.vLog(TAG, "getHighlightStartLoc exit."); return loc; } protected String getHighlightEndLoc() { Logger.vLog(TAG, "getHighlightEndLoc enter>>>"); String loc = com.easyview.ebook.reader.engine.model.Book.VALUE_NULL; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); ZLTextPosition position = view.getSelectionStartPosition(); if (null == position) { return loc; } int pi = position.getParagraphIndex(); int wi = position.getElementIndex(); int ci = position.getCharIndex(); loc = String.format(LOCATION_PREFIX, pi, wi, ci); Logger.vLog(TAG, "getHighlightEndLoc exit."); return loc; } protected boolean delAllHighlight() { Logger.vLog(TAG, "delAllHighlight enter>>>"); boolean res = true; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); view.clearSelection(); Logger.vLog(TAG, "delAllHighlight exit."); return res; } protected String getPageText() { Logger.vLog(TAG, "getPageText enter>>>"); String text; final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); text = view.getCurrentPageText(); Logger.vLog(TAG, "getPageText exit."); return text; } protected void setBitmapConfig(Bitmap.Config config) { mBitmapConfig = config; } protected Bitmap.Config getBitmapConfig() { return mBitmapConfig; } protected void convertMarkToSearchResult(ZLTextMark srcMark, BookSearchResult desResult) { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); ZLTextModel model = view.getModel(); ZLTextWordCursor wordCursor; desResult.start_pos = getLocation(srcMark.ParagraphIndex, srcMark.Offset, srcMark.Length); desResult.end_pos = desResult.start_pos; wordCursor = new ZLTextWordCursor(ZLTextParagraphCursor.cursor(model, srcMark.ParagraphIndex)); desResult.text = getBookmarkText(wordCursor, SUMMARY_MAX_NUM); } protected ZLTextMark convertResultToMark(BookSearchResult desResult) { if ( (null == desResult) || desResult.equals(com.easyview.ebook.reader.engine.model.Book.VALUE_NULL)) { return null; } int[] pos = parseLocation(desResult.start_pos); ZLTextMark mark = new ZLTextMark(pos[0], pos[1], pos[2]); return mark; } // return desString private String convertString(String srcString, String srcCharset, String desCharset) { Charset charsetSrc = Charset.forName(srcCharset); Charset charsetDes = Charset.forName(desCharset); CharsetDecoder decoder = charsetSrc.newDecoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE); CharsetEncoder encoder = charsetDes.newEncoder() .onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE); ByteBuffer bbuf = null; CharBuffer cbuf = null; try { bbuf = encoder.encode(CharBuffer.wrap(srcString)); } catch (CharacterCodingException e) { e.printStackTrace(); return null; } try { cbuf = decoder.decode(bbuf); } catch (CharacterCodingException e) { e.printStackTrace(); return null; } return cbuf.toString(); } // get bookmark summary private String getBookmarkText(ZLTextWordCursor cursor, int maxWords) { cursor = new ZLTextWordCursor(cursor); final StringBuilder builder = new StringBuilder(); final StringBuilder sentenceBuilder = new StringBuilder(); final StringBuilder phraseBuilder = new StringBuilder(); int wordCounter = 0; int sentenceCounter = 0; int storedWordCounter = 0; boolean lineIsNonEmpty = false; boolean appendLineBreak = false; mainLoop: while (wordCounter < maxWords && sentenceCounter < 3) { while (cursor.isEndOfParagraph()) { if (!cursor.nextParagraph()) { break mainLoop; } if ((builder.length() > 0) && cursor.getParagraphCursor().isEndOfSection()) { break mainLoop; } if (phraseBuilder.length() > 0) { sentenceBuilder.append(phraseBuilder); phraseBuilder.delete(0, phraseBuilder.length()); } if (sentenceBuilder.length() > 0) { if (appendLineBreak) { builder.append("\n"); } builder.append(sentenceBuilder); sentenceBuilder.delete(0, sentenceBuilder.length()); ++sentenceCounter; storedWordCounter = wordCounter; } lineIsNonEmpty = false; if (builder.length() > 0) { appendLineBreak = true; } } final ZLTextElement element = cursor.getElement(); // add zenki-zha-xxx, some books may crash if (element == null) { break mainLoop; } if (element instanceof ZLTextWord) { final ZLTextWord word = (ZLTextWord) element; if (lineIsNonEmpty) { phraseBuilder.append(" "); } phraseBuilder.append(word.Data, word.Offset, word.Length); ++wordCounter; lineIsNonEmpty = true; switch (word.Data[word.Offset + word.Length - 1]) { case ',': case ':': case ';': case ')': sentenceBuilder.append(phraseBuilder); phraseBuilder.delete(0, phraseBuilder.length()); break; case '.': case '!': case '?': ++sentenceCounter; if (appendLineBreak) { builder.append("\n"); appendLineBreak = false; } sentenceBuilder.append(phraseBuilder); phraseBuilder.delete(0, phraseBuilder.length()); builder.append(sentenceBuilder); sentenceBuilder.delete(0, sentenceBuilder.length()); storedWordCounter = wordCounter; break; } } cursor.nextWord(); } if (storedWordCounter < 4) { if (sentenceBuilder.length() == 0) { sentenceBuilder.append(phraseBuilder); } if (appendLineBreak) { builder.append("\n"); } builder.append(sentenceBuilder); } return builder.toString(); } // search part end private void initFbreader() { mIes = (IEngineService) ERManager .getService(ERManager.ERENGINE_SERVICE); new ZLAndroidLibrary(mIes.getApplication()); new ZLAndroidImageManager(); // 初始化Config數據庫 // mZlSqlConfig = new ZLSQLiteConfig(mIes.getContext()); // 內容渲染模塊 mBitmapManager = new BitmapManager(); mBitmapManager.setBitmapConfig(getBitmapConfig()); mBitmapManager.reset(); // create in ZLAndroidApplication.java // new ZLAndroidDialogManager(); // new ZLAndroidLibrary(this); } private FBReaderApp createApplication(ZLFile file) { if (SQLiteBooksDatabase.Instance() == null) { mSqlBooksDb = new SQLiteBooksDatabase(mIes.getContext(), "READER"); } return new FBReaderApp(file != null ? file.getPath() : null); } private int searchChapter(String title) { int id = EngineMsgCode.ENGINE_WARN_CHAPTER_JUMP_FAILED; for (int i = 0; i < mChapterTitles.length; i++) { if (mChapterTitles[i].equals(title)) { id = i; break; } } return id; } private int searchChapter(int paragraphIndex) { int id = EngineMsgCode.ENGINE_WARN_CHAPTER_JUMP_FAILED; for (int i = 0; i < mChapterTitles.length; i++) { if (mChapterIndexs[i] == paragraphIndex) { id = i; break; } } Logger.dLog(TAG, "paragraphIndex = " + paragraphIndex + " id = " + id); return id; } private void resetCache() { mChapterIndexs = null; mChapterTitles = null; if (mBitmapManager != null) { mBitmapManager.reset(); } if (mZlApplication != null) { mZlApplication.clearTextCaches(); } // if (mZlSqlConfig != null) { // mZlSqlConfig.closeDatabase(); // } // // if (mSqlBooksDb != null) { // mSqlBooksDb.closeDatabase(); // } Logger.dLog(TAG, "resetCache finished"); } private boolean computerTextSize() { final ZLTextView view = (ZLTextView) mZlApplication.getCurrentView(); ZLTextModel myModel = view.getModel(); if (myModel == null || myModel.getParagraphsNumber() == 0) { return false; } final float factor = view.computeCharsPerPage(); final float textSize = view.computePageNumber() * factor; return true; } }