/**
* @file FbreaderWrapper.java
*
* @revision: none
*
* @version 0.0.01
* @author: Zenki (zhajun), zenki2001cn@163.com
* @date: 2011-4-27 上午09:48:49
*/
package com.easyview.ebook.reader.engine.core.fbreader;
import org.geometerplus.zlibrary.text.model.ZLTextMark;
import android.graphics.Bitmap;
import com.easyview.ebook.reader.engine.core.DecAdapter;
import com.easyview.ebook.reader.engine.core.EngineCode;
import com.easyview.ebook.reader.engine.core.ReaderWrapper;
import com.easyview.ebook.reader.engine.core.EngineCode.EngineMsgCode;
import com.easyview.ebook.reader.engine.core.fbreader.FbreaderAdapter.PageType;
import com.easyview.ebook.reader.engine.model.Book;
import com.easyview.ebook.reader.engine.model.BookSearchInfo;
import com.easyview.ebook.reader.engine.model.FbreaderPage;
import com.easyview.ebook.reader.engine.model.IBookEmphasisCursor;
import com.easyview.ebook.reader.engine.model.IBookMarkCursor;
import com.easyview.ebook.reader.engine.model.IBookSearchCursor;
import com.easyview.ebook.reader.engine.model.Page;
import com.easyview.ebook.reader.engine.model.BookEmphasisInfo.BookEmphasis;
import com.easyview.ebook.reader.engine.model.BookMarkInfo.Bookmark;
import com.easyview.ebook.reader.engine.model.ChapterTreeInfo.ChapterTreeState;
import com.easyview.ebook.reader.engine.util.Logger;
/**
*
*/
public class FbreaderWrapper extends ReaderWrapper {
static private final String TAG = "FbreaderWrapper";
static private FbreaderWrapper mAction;
static private FbreaderAdapter mAdapter;
private final int MAX_FONT_LEVEL = 5;
private final int MIN_FONT_LEVEL = 0;
private final int DEFAULT_FONT_LEVEL = 1;
private final int MAX_FONT_SIZE = 38;
private final int MIN_FONT_SIZE = 18;
private final int FONT_SIZE_DIFF = 4;
private final int FONT_SIZE_2 = MIN_FONT_SIZE + FONT_SIZE_DIFF;
private final int FONT_SIZE_3 = MIN_FONT_SIZE + FONT_SIZE_DIFF * 2;
private final int FONT_SIZE_4 = MIN_FONT_SIZE + FONT_SIZE_DIFF * 3;
private final int FONT_SIZE_5 = MIN_FONT_SIZE + FONT_SIZE_DIFF * 4;
private final int ROTATE_ANGLE = 90;
private int mHighlightStartX = -1;
private int mHighlightStartY = -1;
private int mHighlightEndX = -1;
private int mHighlightEndY = -1;
private int mHighlightColor = -1;
private FbreaderWrapper() {
super();
if (null == mAdapter) {
mAdapter = FbreaderAdapter.getInstance();
mAdapter.setBitmapConfig(getBitmapConfig());
}
}
public static FbreaderWrapper getInstance() {
if (null == mAction) {
mAction = new FbreaderWrapper();
}
return mAction;
}
protected void free() {
super.free();
if (mAdapter != null) {
mAdapter.free();
mAdapter = null;
}
if (mAction != null) {
mAction = null;
}
Logger.dLog(TAG, "ReaderWrapper free mFbreaderAdapter: " + mAdapter
+ " mAction: " + mAction);
}
@Override
protected DecAdapter getCurAdapter() {
return mAdapter;
}
@Override
protected void iCloseBook() {
int code = 0;
if (!canWork()) {
Logger.eLog(TAG, "AssertWork == null");
return;
}
Book book = getBook();
if (book.getOpened()) {
code = mAdapter.closeFile();
if (hasError(code)) {
Logger.eLog(TAG, "Close book error");
} else {
Logger.vLog(TAG, "Close book success");
book.setOpened(false);
}
try {
saveBookDB();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Logger.vLog(TAG, "Book is not opened");
}
}
@Override
protected boolean iLoadBook() {
String bookPath;
if (!canWork()) {
Logger.eLog(TAG, "iLoadBook assertWork failed");
return false;
}
/*
* Step 1. ensure close previous file.
*/
int code = mAdapter.closeFile();
if (hasError(code)) {
Logger.eLog(TAG, "Close previous file error, code = " + code);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
Logger.eLog(TAG, "Thread.sleep error" + e);
}
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOK_CLOSE_PREVIOUS_FAILED);
} else {
Logger.dLog(TAG, "Close previous file ok");
}
/*
* Step 2 get file path name and open file.
*/
Book book = getBook();
bookPath = book.getBookPath();
code = mAdapter.openFile(bookPath);
if (hasError(code)) {
Logger.eLog(TAG, "Open book error, code = " + code);
try {
Thread.sleep(30);
} catch (InterruptedException e) {
Logger.eLog(TAG, "Thread.sleep error" + e);
}
return false;
} else {
Logger.vLog(TAG, "Open book success");
}
/*
* Step 3.
*/
try {
// FBReader維持自己的數據庫用來保存最後頁碼、字體大小等等信息。
mAdapter.setViewPortSize(book.getViewWidth(), book.getViewHeight());
FbreaderPage page = (FbreaderPage) book.getCurPage();
FbreaderPage cache = (FbreaderPage) book.getCachePage();
// 消除最後一頁字符重疊的現象
eliminateCharDuplication();
// TXT文档处理时需要多加载一次页码,以免不能跳到首页
if (Book.BookType.TXT == book.getBookType()) {
getPage(cache);
}
if (book.getLastLocation().equals(Book.VALUE_NULL)) {
mAdapter.gotoHome();
} else {
int[] pos = mAdapter.parseLocation(book.getLastLocation());
if ((pos[0] == -1) || (pos[1] == -1) || (pos[2] == -1)) {
} else {
mAdapter.gotoPosition(pos[0], pos[1], pos[2]);
}
}
// 跳轉到最後頁碼,解決字符重疊問題
// mTotalNumber = mAdapter.getTotalPageIndex();
// lastPage = book.getLastPageNumber();
// if (lastPage > mTotalNumber || lastPage <= 0) {
// Logger.vLog(TAG, "PageNum is not invalid");
// setLastCode(EngineMsgCode.ENGINE_ERROR_PAGE_NUMBER_INVALID);
// } else {
// mAdapter.gotoPage(lastPage);
// }
// goto position
// if (!book.getLastLocation().equals(Book.VALUE_NULL)) {
// int[] pos = mAdapter.parseLocation(book.getLastLocation());
// if ((pos[0] == -1) || (pos[1] == -1) || (pos[2] == -1)) {
// } else {
// mAdapter.gotoPosition(pos[0], pos[1], pos[2]);
// }
// }
getPage(page);
updateView();
Book.MetaData data = book.getMetaData();
if (data.isEmpty()) {
String title = mAdapter.getTitle();
String author = mAdapter.getAuthor();
String encoding = mAdapter.getEncoding();
String language = mAdapter.getLanguage();
// Logger.dLog(TAG, "FbreaderWrapper debug title = " + title +
// " author = " + author +
// " encoding = " + encoding +
// " language = " + language);
data.setValue(Book.MetaData.META_TITLE,
((title != null) ? title : Book.VALUE_NULL));
data.setValue(Book.MetaData.META_AUTHOR,
((author != null) ? author : Book.VALUE_NULL));
data.setValue(Book.MetaData.META_ENCODING,
((encoding != null) ? encoding : Book.VALUE_NULL));
data.setValue(Book.MetaData.META_LANGUAGE,
((language != null) ? language : Book.VALUE_NULL));
book.setMetaData(data);
}
// 获取封面图片路径
// Logger.dLog(TAG, "getCover = " + mAdapter.getCoverUri());
// 打印metadata信息
// data.dumpvalue();
int totalNumber = mAdapter.getTotalPageNum();
setCurFontLevel(fontSize2Level(mAdapter.getFontSize()));
book.setTotalPageNumber(totalNumber);
book.setLastAccessTime(System.currentTimeMillis());
book.setOpened(true);
updateBookInfo(page);
} catch (Exception e) {
Logger.eLog(TAG, "Load book error");
return false;
}
return true;
}
@Override
protected void iLoadChapterInformation() {
String[] chapters;
int[] indexs;
if (!canWork()) {
Logger.eLog(TAG, "iLoadChapterInformation assertWork failed");
return;
}
Book book = getBook();
if (!book.chapterIsLoad()) {
if (mAdapter.getChapterNumber() > 0) {
chapters = mAdapter.getChapterTitles();
indexs = mAdapter.getChapterIndexs();
book.chapterInit(indexs, chapters);
} else {
book.chapterInit(null, null);
}
Logger.dLog(TAG,
"loadChapterInfo finished == " + book.chapterIsLoad());
}
}
@Override
protected void iChapterJumpByTitle(String title) {
if (!canWork()) {
Logger.eLog(TAG, "iChapterJumpByTitle assertWork failed");
return;
}
int code = mAdapter.goToChapterByTitle(title);
if (hasError(code)) {
return;
}
Book book = getBook();
try {
FbreaderPage page = (FbreaderPage) book.getCurPage();
getPage(page);
setBorder(false);
updateView();
updateBookInfo(page);
book.resetPrePage();
book.resetNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "ichapterJumpTo failed");
}
Logger.vLog(TAG, "ichapterJumpTo finished");
}
@Override
protected void iChapterJumpByIndex(int index) {
if (!canWork()) {
Logger.eLog(TAG, "iChapterJumpByIndex assertWork failed");
return;
}
Book book = getBook();
if (index < 0 || index >= book.getMaxChapterNum()) {
Logger.dLog(TAG, "Chapter index out of bounds!");
setLastCode(EngineMsgCode.ENGINE_WARN_CHAPTER_JUMP_FAILED);
return;
}
int code = mAdapter.goToChapterByIndex(index);
if (hasError(code)) {
return;
}
try {
FbreaderPage page = (FbreaderPage) book.getCurPage();
getPage(page);
setBorder(false);
updateView();
updateBookInfo(page);
book.resetPrePage();
book.resetNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "ichapterJumpTo failed");
}
Logger.vLog(TAG, "ichapterJumpTo finished");
}
@Override
protected void iChapterUp() {
if (!canWork()) {
Logger.eLog(TAG, "iChapterUp assertWork failed");
return;
}
Book book = getBook();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
int curIndex = mAdapter.getCurrentParagraphIndex();
if (book.hasPreviousChapter()) {
int preIndex = book.getPreviousChapterIndex(curIndex);
Logger.eLog(TAG, "iChapterUp preIndex = " + preIndex);
int code = mAdapter.goToChapterByIndex(preIndex);
if (hasError(code)) {
return;
}
try {
curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
book.resetPrePage();
book.resetNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "ichapterUp failed ");
}
// debug code, can be delete
// int curIndex = mOpenedBook.getCurChapterIndex();
// int pageIndex = mOpenedBook.chapterGetCurPageIndex(curIndex);
// Logger.vLog(TAG, "ichapterUp finished " + curIndex + " -- " +
// pageIndex);
} else {
Logger.vLog(TAG, "hasPreviousChapter = false");
setLastCode(EngineMsgCode.ENGINE_WARN_CHAPTER_UP_FAILED);
}
}
@Override
protected void iChapterDown() {
if (!canWork()) {
Logger.eLog(TAG, "iChapterDown assertWork failed");
return;
}
Book book = getBook();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
int curIndex = mAdapter.getCurrentParagraphIndex();
if (book.hasNextChapter()) {
int nextIndex = book.getNextChapterIndex(curIndex);
Logger.eLog(TAG, "iChapterUp nextIndex = " + nextIndex);
int code = mAdapter.goToChapterByIndex(nextIndex);
if (hasError(code)) {
return;
}
try {
curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
book.resetPrePage();
book.resetNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "ichapterUp failed");
}
// debug code, can be delete
// int curIndex = mOpenedBook.getCurChapterIndex();
// int pageIndex = mOpenedBook.chapterGetCurPageIndex(curIndex);
// Logger.vLog(TAG, "ichapterUp finished " + curIndex + " -- " +
// pageIndex);
} else {
Logger.vLog(TAG, "hasNextChapter = false");
setLastCode(EngineMsgCode.ENGINE_WARN_CHAPTER_DOWN_FAILED);
}
}
@Override
protected void iChapterUpdateInfo() {
if (!canWork()) {
Logger.eLog(TAG, "iChapterUpdateInfo assertWork failed");
return;
}
Book book = getBook();
if (book.chapterIsLoad()) {
if (book.chapterIsEmpty()) {
book.setCurChapterIndex(-1);
} else {
book.setCurChapterIndex(mAdapter.getCurrentChapterIndex());
book.setChapterState(ChapterTreeState.CURRENT_LOADED);
// Logger.dLog(
// TAG,
// "Tree.getCurChapterIndex(): "
// + book.getCurChapterIndex()
// + " Tree.getMaxChapterNum():"
// + book.getMaxChapterNum());
}
}
}
@Override
protected boolean iPageUp() {
if (!canWork()) {
Logger.eLog(TAG, "iPageDown assertWork failed");
return false;
}
boolean hasPrePage = false;
Book book = getBook();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
FbreaderPage prePage = (FbreaderPage) book.getPrePage();
try {
hasPrePage = mAdapter.pageUp();
if (!hasPrePage) {
setBorder(true);
book.resetNextPage();
book.resetPrePage();
return false;
} else {
setBorder(false);
}
if (prePage.isLoaded()) {
Logger.vLog(TAG, "PrePage is loaded");
// 只有跳到当前页才能得到页码和位置信息
prePage.setPageNum(mAdapter.getCurrentPageNum());
prePage.setLocation(mAdapter.getLocation());
// if (mAdapter.isHeadParagraph()) {
// nextPage.reset();
// } else {
// nextPage.copy(curPage);
// }
curPage.copy(prePage);
updateView();
} else {
Logger.vLog(TAG, "PrePage is not loaded");
curPage.reset();
if (getPage(curPage)) {
updateView();
}
}
Logger.vLog(TAG, "Has PrePage = " + hasPrePage);
// update Book information
updateBookInfo(curPage);
// preloadNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "TurnPageUp error");
setLastCode(EngineMsgCode.STATE_ERROR_PAGE_UP_FAILED);
return false;
}
return true;
}
@Override
protected boolean iPageDown() {
if (!canWork()) {
Logger.eLog(TAG, "iPageDown assertWork failed");
return false;
}
boolean hasNextPage = false;
Book book = getBook();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
FbreaderPage nextPage = (FbreaderPage) book.getNextPage();
try {
hasNextPage = mAdapter.pageDown();
if (!hasNextPage) {
setBorder(true);
book.resetNextPage();
book.resetPrePage();
return false;
} else {
setBorder(false);
}
if (nextPage.isLoaded()) {
Logger.vLog(TAG, "NextPage is loaded");
// 只有跳到当前页才能得到页码和位置信息
nextPage.setPageNum(mAdapter.getCurrentPageNum());
nextPage.setLocation(mAdapter.getLocation());
curPage.copy(nextPage);
updateView();
} else {
Logger.vLog(TAG, "NextPage is not loaded");
curPage.reset();
if (getPage(curPage)) {
updateView();
}
}
Logger.vLog(TAG, "Has nextpage = " + hasNextPage);
// update Book information
updateBookInfo(curPage);
// preloadPreviousPage();
} catch (Exception e) {
Logger.eLog(TAG, "TurnPageDown error");
setLastCode(EngineMsgCode.STATE_ERROR_PAGE_DOWN_FAILED);
return false;
}
return true;
}
@Override
protected boolean iPageJumpTo(int pageNum) {
if (!canWork()) {
Logger.eLog(TAG, "iPageJumpTo assertWork failed");
return false;
}
Book book = getBook();
// 该方法不能正确跳转到最后一页
// int pageNum = num - 1;
// if (pageNum >= mTotalNumber) {
// pageNum = mTotalNumber - 1;
// } else if (pageNum <= 0) {
// pageNum = 0;
// }
// 该方法不能正确跳转到第一页
if ((pageNum > book.getTotalPageNumber()) || (pageNum <= 0)) {
Logger.vLog(TAG, "PageNum is not invalid");
setLastCode(EngineMsgCode.ENGINE_ERROR_PAGE_NUMBER_INVALID);
return false;
}
try {
if (pageNum == 1) {
mAdapter.gotoHome();
} else {
mAdapter.gotoPage(pageNum);
}
// eliminateCharDuplication();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
// Empty the cache, otherwise it would cause an error when render
book.resetNextPage();
book.resetPrePage();
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iPageJumpTo error");
setLastCode(EngineMsgCode.STATE_ERROR_GOTO_PAGE_FAILED);
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see
* com.easyview.ebook.reader.engine.core.ReaderWrapper#iPageZoomLevel(int)
*/
@Override
protected boolean iPageZoomLevel(int lv) {
if (!canWork()) {
Logger.eLog(TAG, "iPageZoomLevel assertWork failed");
return false;
}
int curFontLev = getCurFontLevel();
int desFontLev;
if (lv > MAX_FONT_LEVEL) {
desFontLev = MAX_FONT_LEVEL;
} else if (lv < MIN_FONT_LEVEL) {
desFontLev = MIN_FONT_LEVEL;
} else {
desFontLev = lv;
}
Book book = getBook();
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
int loop;
if (curFontLev < desFontLev) {
loop = desFontLev - curFontLev;
for (int i = 0; i < loop; i++) {
mAdapter.zoomIn();
mAdapter.getBitmap(PageType.CurrentPage);
}
} else if (curFontLev > desFontLev) {
loop = curFontLev - desFontLev;
for (int i = 0; i < loop; i++) {
mAdapter.zoomOut();
mAdapter.getBitmap(PageType.CurrentPage);
}
}
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
book.resetPrePage();
book.resetNextPage();
// update Book information
book.setTotalPageNumber(mAdapter.getTotalPageNum());
setCurFontLevel(fontSize2Level(mAdapter.getFontSize()));
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iPageZoomLevel error");
setLastCode(EngineMsgCode.STATE_ERROR_ZOOM_LEVEL_FAILED);
return false;
}
return true;
}
@Override
protected boolean iPageZoomIn() {
int fontLevel = fontSize2Level(mAdapter.getFontSize());
if (fontLevel >= MAX_FONT_LEVEL) {
setLastCode(EngineMsgCode.ENGINE_WARN_MAX_FONT);
return false;
}
if (!canWork()) {
Logger.eLog(TAG, "iPageZoomIn assertWork failed");
return false;
}
Book book = getBook();
try {
mAdapter.zoomIn();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
// Empty the cache, otherwise it would cause an error when render
book.resetNextPage();
book.resetPrePage();
// update book info
book.setTotalPageNumber(mAdapter.getTotalPageNum());
setCurFontLevel(fontSize2Level(mAdapter.getFontSize()));
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iPageZoomIn error");
setLastCode(EngineMsgCode.STATE_ERROR_ZOOM_IN_FAILED);
return false;
}
return true;
}
@Override
protected boolean iPageZoomOut() {
int fontLevel = fontSize2Level(mAdapter.getFontSize());
Logger.dLog(TAG, "font = " + fontLevel);
if (fontLevel <= MIN_FONT_LEVEL) {
setLastCode(EngineMsgCode.ENGINE_WARN_MIN_FONT);
return false;
}
if (!canWork()) {
Logger.eLog(TAG, "iPageZoomOut assertWork failed");
return false;
}
Book book = getBook();
try {
mAdapter.zoomOut();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
// Empty the cache, otherwise it would cause an error when render
book.resetNextPage();
book.resetPrePage();
book.setTotalPageNumber(mAdapter.getTotalPageNum());
setCurFontLevel(fontSize2Level(mAdapter.getFontSize()));
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "ZoomOut error");
setLastCode(EngineMsgCode.STATE_ERROR_ZOOM_OUT_FAILED);
return false;
}
return true;
}
@Override
protected void preloadPage() {
preloadPreviousPage();
preloadNextPage();
}
@Override
protected boolean preloadPreviousPage() {
if (!canWork()) {
Logger.eLog(TAG, "preloadPreviousPage assertWork failed");
return false;
}
Book book = getBook();
// if (!mAdapter.pageUp()) {
// book.resetNextPage();
// book.resetPrePage();
// // mAdapter.pageDown();
//
// return false;
// }
//
// FbreaderPage prePage = (FbreaderPage) book.getPrePage();
//
// prePage.reset();
// getPage(prePage);
//
// mAdapter.pageDown();
FbreaderPage prePage = (FbreaderPage) book.getPrePage();
getPrePage(prePage);
return true;
}
@Override
protected boolean preloadNextPage() {
if (!canWork()) {
Logger.eLog(TAG, "preloadNextPage assertWork failed");
return false;
}
Book book = getBook();
// if (!mAdapter.isEndParagraph()) {
// mAdapter.pageDown();
// FbreaderPage nextPage = (FbreaderPage) book.getNextPage();
//
// nextPage.reset();
// getPage(nextPage);
// } else {
// // mAdapter.nextParagraph();
// // book.resetNextPage();
// book.resetPrePage();
// return false;
// }
//
// mAdapter.pageUp();
FbreaderPage nextPage = (FbreaderPage) book.getNextPage();
getNextPage(nextPage);
return true;
}
private boolean getPrePage(FbreaderPage page) {
if (!canWork()) {
Logger.eLog(TAG, "getPrePage assertWork failed");
return false;
}
Bitmap bmp = null;
Book book = getBook();
int width = book.getViewWidth();
int height = book.getViewHeight();
try {
bmp = Bitmap
.createBitmap(mAdapter.getBitmap(PageType.PreviousPage));
// if (true == getLandMode()) {
// Matrix m = new Matrix();
// m.postRotate(ROTATE_ANGLE);
// bmp = Bitmap.createBitmap(bmp, 0, 0, width, height, m, false);
// }
if (null == bmp) {
Logger.dLog(TAG, "getBitmap bmp == " + bmp);
return false;
}
} catch (OutOfMemoryError e) {
setLastCode(EngineCode.EngineMsgCode.ENGINE_FATAL_OUTOF_MEMORY);
Logger.dLog(TAG, "getBitmap Exception == " + e);
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
page.setPageContent(bmp);
int index = mAdapter.getCurrentPageNum();
page.setPageNum(index);
page.setLocation(mAdapter.getLocation());
page.setSummary(mAdapter.getSummary());
page.setLoaded(true);
return true;
}
private int fontSize2Level(int size) {
int level = 2;
if (size <= MIN_FONT_SIZE) {
level = 0;
} else if ((size > MIN_FONT_SIZE) && (size <= FONT_SIZE_2)) {
level = 1;
} else if ((size > FONT_SIZE_2) && (size <= FONT_SIZE_3)) {
level = 2;
} else if ((size > FONT_SIZE_3) && (size <= FONT_SIZE_4)) {
level = 3;
} else if ((size > FONT_SIZE_4) && (size <= FONT_SIZE_5)) {
level = 4;
} else if (size > FONT_SIZE_5) {
level = 5;
}
return level;
}
private int level2FontSize(int lev) {
int size = 26;
switch (lev) {
case 0:
size = 18;
break;
case 1:
size = 22;
break;
case 2:
size = 26;
break;
case 3:
size = 30;
break;
case 4:
size = 34;
break;
default:
break;
}
return size;
}
private void resetHighlight() {
mHighlightStartX = -1;
mHighlightStartY = -1;
mHighlightEndX = -1;
mHighlightEndY = -1;
mHighlightColor = -1;
}
private boolean getNextPage(FbreaderPage page) {
if (!canWork()) {
Logger.eLog(TAG, "getNextPage assertWork failed");
return false;
}
Bitmap bmp = null;
Book book = getBook();
int width = book.getViewWidth();
int height = book.getViewHeight();
try {
bmp = Bitmap.createBitmap(mAdapter.getBitmap(PageType.NextPage));
// if (true == getLandMode()) {
// Matrix m = new Matrix();
// m.postRotate(ROTATE_ANGLE);
// bmp = Bitmap.createBitmap(bmp, 0, 0, width, height, m, false);
// }
if (null == bmp) {
Logger.dLog(TAG, "getBitmap bmp == " + bmp);
return false;
}
} catch (OutOfMemoryError e) {
setLastCode(EngineCode.EngineMsgCode.ENGINE_FATAL_OUTOF_MEMORY);
Logger.dLog(TAG, "getBitmap Exception == " + e);
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
page.setPageContent(bmp);
int index = mAdapter.getCurrentPageNum();
page.setPageNum(index);
page.setLocation(mAdapter.getLocation());
page.setSummary(mAdapter.getSummary());
page.setLoaded(true);
return true;
}
private boolean getPage(FbreaderPage page) {
if (!canWork()) {
Logger.eLog(TAG, "getPage assertWork failed");
return false;
}
Bitmap bmp = null;
Book book = getBook();
int width = book.getViewWidth();
int height = book.getViewHeight();
try {
bmp = Bitmap.createBitmap(mAdapter.getBitmap(PageType.CurrentPage));
// if (true == getLandMode()) {
// Matrix m = new Matrix();
// m.postRotate(ROTATE_ANGLE);
// bmp = Bitmap.createBitmap(bmp, 0, 0, width, height, m, false);
// }
if (null == bmp) {
Logger.dLog(TAG, "getBitmap bmp == " + bmp);
return false;
}
} catch (OutOfMemoryError e) {
setLastCode(EngineCode.EngineMsgCode.ENGINE_FATAL_OUTOF_MEMORY);
Logger.dLog(TAG, "getBitmap Exception == " + e);
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
page.setPageContent(bmp);
int index = mAdapter.getCurrentPageNum();
page.setPageNum(index);
page.setLocation(mAdapter.getLocation());
page.setSummary(mAdapter.getSummary());
page.setLoaded(true);
return true;
}
private void updateBookInfo(Page page) {
Book book = getBook();
if (book != null) {
book.updateFromPage(page);
book.setFontLevel(getCurFontLevel());
}
}
// 通過向上翻頁、再向下翻頁、再向下翻頁、再向上翻頁用來消除定位不准,字符重疊的現象
private void eliminateCharDuplication() {
FbreaderPage cache = (FbreaderPage) getBook().getCachePage();
mAdapter.pageUp();
mAdapter.getBitmap(PageType.CurrentPage);
mAdapter.pageDown();
mAdapter.getBitmap(PageType.CurrentPage);
mAdapter.pageDown();
getPage(cache);
mAdapter.pageUp();
getPage(cache);
cache.reset();
}
@Override
protected void iEnterSearchMode() {
if (!canWork()) {
Logger.eLog(TAG, "iEnterSearchMode assertWork failed");
return;
}
BookSearchInfo.BookSearchResult[] results;
Book book = getBook();
IBookSearchCursor bookSearchOps = book.getBookSearchCursor();
String key = bookSearchOps.getSearchKeyword();
if ((null == key) || key.equalsIgnoreCase("")) {
Logger.vLog(TAG, "iEnterSearchMode key == null");
setLastCode(EngineMsgCode.ENGINE_WARN_SEARCH_KEY_NULL);
return;
}
mAdapter.quitSearch();
setLastCode(EngineCode.EngineMsgCode.NO_ERROR);
mAdapter.gotoHome();
int code = mAdapter.startSearch(key);
if (0 == code) {
setLastCode(EngineMsgCode.ENGINE_WARN_SEARCH_RESULT_NULL);
return;
}
bookSearchOps.resetResults();
results = mAdapter.getSearchResult();
if (results != null) {
bookSearchOps.addResults(results);
}
// debug code, can be delete
// for (BookSearchInfo.BookSearchResult searchResult : results) {
// Logger.dLog(TAG, "iEnterSearchMode text = " + searchResult.text +
// " start = "
// + searchResult.start_pos + " end = " + searchResult.end_pos);
// }
iSearchGoNext();
book.resetNextPage();
book.resetPrePage();
}
@Override
protected void iSearchGoNext() {
if (!canWork()) {
Logger.eLog(TAG, "iSearchGoNext assertWork failed");
return;
}
Book book = getBook();
IBookSearchCursor bookSearchOps = book.getBookSearchCursor();
// check keyword
String key = bookSearchOps.getSearchKeyword();
if ((null == key) || key.equalsIgnoreCase("")) {
Logger.vLog(TAG, "iSearchGoNext key == null");
setLastCode(EngineMsgCode.ENGINE_WARN_SEARCH_KEY_NULL);
return;
}
int code = mAdapter.searchNext();
if (hasError(code)) {
Logger.eLog(TAG, "iSearchGoNext hasError");
setLastCode(code);
return;
}
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iSearchGoNext failed");
}
}
@Override
protected void iSearchGoPrevious() {
if (!canWork()) {
Logger.eLog(TAG, "iSearchGoPrevious assertWork failed");
return;
}
Book book = getBook();
IBookSearchCursor bookSearchOps = book.getBookSearchCursor();
// check keyword
String key = bookSearchOps.getSearchKeyword();
if ((null == key) || key.equalsIgnoreCase("")) {
Logger.vLog(TAG, "iSearchGoPrevious key == null");
setLastCode(EngineMsgCode.ENGINE_WARN_SEARCH_KEY_NULL);
return;
}
int code = mAdapter.searchPrevious();
if (hasError(code)) {
Logger.eLog(TAG, "iSearchGoPrevious hasError");
setLastCode(code);
return;
}
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iSearchGoNext failed");
}
}
/*
* (non-Javadoc)
*
* @see
* com.easyview.ebook.reader.engine.core.ReaderWrapper#iSearchGoto(com.easyview
* .ebook.reader.engine.model.BookSearchInfo.BookSearchResult)
*/
@Override
protected void iSearchGoto(
com.easyview.ebook.reader.engine.model.BookSearchInfo.BookSearchResult result) {
if (!canWork()) {
Logger.eLog(TAG, "iSearchGoto assertWork failed");
return;
}
Book book = getBook();
if ((null == result) || (result.start_pos.equals(Book.VALUE_NULL))) {
setLastCode(EngineMsgCode.STATE_ERROR_SEARCH_GOTO_RESULT_FAILED);
return;
}
ZLTextMark mark = mAdapter.convertResultToMark(result);
if (null == mark) {
setLastCode(EngineMsgCode.STATE_ERROR_SEARCH_GOTO_RESULT_FAILED);
return;
}
try {
mAdapter.gotoMark(mark);
FbreaderPage page = (FbreaderPage) book.getCurPage();
getPage(page);
setBorder(false);
updateView();
updateBookInfo(page);
} catch (Exception e) {
Logger.eLog(TAG, "iSearchGoto failed");
}
}
@Override
protected void iSearchUpdateInfo() {
// TODO Auto-generated method stub
}
@Override
protected void iQuitSearch() {
Logger.eLog(TAG, "iQuitSearch >>>");
mAdapter.quitSearch();
// clear search keyword
Book book = getBook();
IBookSearchCursor bookSearchOps = book.getBookSearchCursor();
bookSearchOps.setSearchKeyword(null);
// reset error code
setLastCode(EngineCode.EngineMsgCode.NO_ERROR);
}
@Override
protected void iAddBookmark() {
if (!canWork()) {
Logger.eLog(TAG, "iAddBookmark assertWork failed");
return;
}
try {
Book book = getBook();
String location = mAdapter.getLocation();
// 判斷當前頁是否已存在書簽,該邏輯移到ERSqliteProxy中處理
// IDatabaseService dbService = (IDatabaseService) ERManager
// .getService(ERManager.DATABASE_SERVICE);
// boolean hasBookmark = dbService.queryBookmark(book, location);
// if (hasBookmark) {
// Logger.dLog(TAG, "iAddBookmark has bookmark");
// return;
// }
FbreaderPage page = (FbreaderPage) book.getCurPage();
IBookMarkCursor bookmarkOps = book.getBookMarkCursor();
Bookmark bookmark = book.makeBookmark();
int pageNum = (int) mAdapter.getCurrentPageNum();
String summary = mAdapter.getSummary();
Logger.vLog(TAG, "iAddBookmark summary = " + summary);
page.setSummary(summary);
bookmark.setLocation(location);
bookmark.setPageNum(pageNum);
bookmark.setSummary(summary);
bookmark.setTime(System.currentTimeMillis());
boolean addRes = bookmarkOps.addBookmark(bookmark);
addBookMarkDB(bookmark);
} catch (Exception e) {
e.printStackTrace();
Logger.eLog(TAG, "iAddBookmark e = " + e);
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOKMARK_ADD_FAILED);
}
}
/*
* (non-Javadoc)
*
* @see
* com.easyview.ebook.reader.engine.core.ReaderWrapper#iGotoBookmark(com.
* easyview.ebook.reader.engine.model.BookMarkInfo.Bookmark)
*/
@Override
protected void iGotoBookmark(Bookmark bookmark) {
if (!canWork()) {
Logger.eLog(TAG, "iGotoBookmark2 assertWork failed");
return;
}
if ((null == bookmark)
|| (bookmark.getLocation().equals(Book.VALUE_NULL))) {
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOKMARK_GOTO_FAILED);
return;
}
Book book = getBook();
FbreaderPage page = (FbreaderPage) book.getCurPage();
int[] pos = mAdapter.parseLocation(bookmark.getLocation());
if ((pos[0] == -1) || (pos[1] == -1) || (pos[2] == -1)) {
} else {
mAdapter.gotoPosition(pos[0], pos[1], pos[2]);
}
getPage(page);
updateView();
updateBookInfo(page);
}
@Override
protected void iGotoBookmark() {
if (!canWork()) {
Logger.eLog(TAG, "iGotoBookmark assertWork failed");
return;
}
Book book = getBook();
IBookMarkCursor bookmarkOps = book.getBookMarkCursor();
Bookmark bookmark = bookmarkOps.getBookmarkTogo();
iGotoBookmark(bookmark);
}
@Override
protected void iDeleteBookmark(Bookmark bookmark) {
if (!canWork()) {
Logger.eLog(TAG, "iDeleteBookmark assertWork failed");
return;
}
if (null == bookmark) {
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOKMARK_DEL_FAILED);
return;
}
try {
Book book = getBook();
IBookMarkCursor bookmarkOps = book.getBookMarkCursor();
bookmarkOps.delBookmark(bookmark);
delBookMarkDB(bookmark);
} catch (Exception e) {
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOKMARK_DEL_FAILED);
}
}
@Override
protected void iDelAllBookmark() {
if (!canWork()) {
Logger.eLog(TAG, "iDelAllBookmark assertWork failed");
return;
}
try {
Book book = getBook();
IBookMarkCursor bookmarkOps = book.getBookMarkCursor();
bookmarkOps.cleanBookmarks();
cleanBookMarkDB();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected boolean iOpenLinkByTouch(int x, int y) {
if (!canWork()) {
Logger.eLog(TAG, "iOpenLinkByTouch assertWork failed");
return false;
}
mAdapter.openLinkByTouch(x, y);
Book book = getBook();
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
// Empty the cache, otherwise it would cause an error when render
book.resetNextPage();
book.resetPrePage();
updateBookInfo(curPage);
} catch (Exception e) {
Logger.eLog(TAG, "iOpenLinkByTouch error");
return false;
}
return true;
}
@Override
protected boolean iResizeScreen(int width, int height) {
if (!canWork()) {
Logger.eLog(TAG, "iSetScreenLandMode assertWork failed");
return false;
}
// if (getLandMode() == land) {
// Logger.dLog(TAG, "iSetScreenLandMode land mode is " + land);
// return false;
// }
//
// setLandMode(land);
Book book = getBook();
book.setViewWidth(width);
book.setViewHeight(height);
book.initPage();
Logger.dLog(TAG, "width = " + width + " height = " + height);
mAdapter.setViewPortSize(width, height);
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
book.resetPrePage();
book.resetNextPage();
} catch (Exception e) {
Logger.eLog(TAG, "iSetScreenLandMode failed");
}
return true;
}
@Override
protected boolean iGotoHighlight(BookEmphasis emphasis) {
if (!canWork()) {
Logger.eLog(TAG, "iDelHighlightByXY assertWork failed");
return false;
}
Book book = getBook();
String location = emphasis.pageLocation;
int x1 = (int) emphasis.startX;
int y1 = (int) emphasis.startY;
int x2 = (int) emphasis.endX;
int y2 = (int) emphasis.endY;
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
int[] pos = mAdapter.parseLocation(location);
if ((pos[0] == -1) || (pos[1] == -1) || (pos[2] == -1)) {
} else {
mAdapter.gotoPosition(pos[0], pos[1], pos[2]);
}
int fontLevel = getCurFontLevel();
if (fontLevel < emphasis.fontLevel) {
while (fontLevel < emphasis.fontLevel) {
mAdapter.zoomIn();
mAdapter.getBitmap(PageType.CurrentPage);
fontLevel = fontSize2Level(mAdapter.getFontSize());
}
} else if (fontLevel > emphasis.fontLevel) {
while (fontLevel > emphasis.fontLevel) {
mAdapter.zoomOut();
mAdapter.getBitmap(PageType.CurrentPage);
fontLevel = fontSize2Level(mAdapter.getFontSize());
}
}
mAdapter.startHighlightByXY(x1, y1);
mAdapter.moveHighlightByXY(x2, y2);
mAdapter.endHighlightByXY(x2, y2);
getPage(curPage);
setBorder(false);
updateView();
setCurFontLevel(fontSize2Level(mAdapter.getFontSize()));
updateBookInfo(curPage);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
@Override
protected boolean iDelHighlight(BookEmphasis emphasis) {
if (!canWork()) {
Logger.eLog(TAG, "iDelHighlightByXY assertWork failed");
return false;
}
String hitStr1 = emphasis.startCursor;
String hitStr2 = emphasis.endCursor;
int color = emphasis.color;
boolean res = mAdapter.delAllHighlight();
Logger.dLog(TAG, "iDelHighlightByXY res = " + res + " hit1 = "
+ hitStr1 + " hit2 = " + hitStr2 + " color = " + color);
if (!res) {
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOK_DEL_HIGHLIGHT_FAILED);
return false;
}
Book book = getBook();
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
IBookEmphasisCursor beops = book.getBookEmphasisCursor();
beops.delEmphasis(emphasis);
delBookEmphasisDB(emphasis);
} catch (Exception e) {
Logger.eLog(TAG, "iDelHighlightByXY failed");
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOK_DEL_HIGHLIGHT_FAILED);
}
return true;
}
@Override
protected boolean iDelAllHighlight() {
if (!canWork()) {
Logger.eLog(TAG, "iDelHighlightByXY assertWork failed");
return false;
}
try {
Book book = getBook();
IBookEmphasisCursor beops = book.getBookEmphasisCursor();
beops.clear();
mAdapter.delAllHighlight();
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
getPage(curPage);
setBorder(false);
updateView();
updateBookInfo(curPage);
cleanBookEmphasisDB();
} catch (Exception e) {
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOK_DEL_HIGHLIGHT_FAILED);
}
return true;
}
@Override
protected boolean iStartHighlightByXY(double x, double y) {
if (!canWork()) {
Logger.eLog(TAG, "iStartHighlightByXY assertWork failed");
return false;
}
mHighlightStartX = (int) x;
mHighlightStartY = (int) y;
mHighlightColor = 0;
mAdapter.startHighlightByXY(mHighlightStartX, mHighlightStartY);
return true;
}
@Override
protected boolean iMoveHighlightByXY(double x, double y) {
if (!canWork()) {
Logger.eLog(TAG, "iMoveHighlightByXY assertWork failed");
return false;
}
mAdapter.moveHighlightByXY((int) x, (int) y);
Book book = getBook();
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
} catch (Exception e) {
Logger.eLog(TAG, "iMoveHighlightByXY error");
return false;
}
return true;
}
@Override
protected boolean iEndHighlightByXY(double x, double y) {
if (!canWork()) {
Logger.eLog(TAG, "iEndHighlightByXY assertWork failed");
return false;
}
mHighlightEndX = (int) x;
mHighlightEndY = (int) y;
mAdapter.endHighlightByXY(mHighlightEndX, mHighlightEndY);
Book book = getBook();
try {
FbreaderPage curPage = (FbreaderPage) book.getCurPage();
curPage.reset();
getPage(curPage);
setBorder(false);
updateView();
// Empty the cache, otherwise it would cause an error when render
book.resetNextPage();
book.resetPrePage();
updateBookInfo(curPage);
BookEmphasis emp = book.makeEmphasis();
IBookEmphasisCursor beops = book.getBookEmphasisCursor();
String location = mAdapter.getLocation();
String summary = mAdapter.getSelectedText();
emp.setXY(mHighlightStartX, mHighlightStartY, mHighlightEndX,
mHighlightEndY);
emp.setCourse(mAdapter.getHighlightStartLoc(),
mAdapter.getHighlightEndLoc());
emp.setLocation(location);
emp.setColor(mHighlightColor);
emp.setTime(System.currentTimeMillis());
emp.setSummary(summary);
emp.setFontLevel(getCurFontLevel());
boolean addRes = beops.addEmphasis(emp);
addBookEmphasisDB(emp);
resetHighlight();
} catch (Exception e) {
Logger.eLog(TAG, "iEndHighlightByXY error");
setLastCode(EngineMsgCode.ENGINE_ERROR_BOOK_ADD_HIGHLIGHT_FAILED);
return false;
}
return true;
}
/*
* (non-Javadoc)
*
* @see com.easyview.ebook.reader.engine.core.ReaderWrapper#iDoFetchText()
*/
@Override
protected boolean iDoFetchText() {
if (!canWork()) {
Logger.eLog(TAG, "iDoFetchText assertWork failed");
return false;
}
Book book = getBook();
String text = mAdapter.getPageText();
if ((null == text)) {
return false;
}
book.setPageText(text);
return true;
}
@Override
protected void setDefaultVal() {
setCurFontLevel(DEFAULT_FONT_LEVEL);
}
}