diff --git a/VERSION b/VERSION index d3532a107..659914ae9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.7 +0.5.8 diff --git a/build_sources_archive.sh b/build_sources_archive.sh deleted file mode 100755 index 393caf329..000000000 --- a/build_sources_archive.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh - -version=`cat VERSION` -intversion=`echo $version | sed "s/\\./0/g" | sed -E "s/^0+//"` -dir=FBReaderJ-sources-$version -archive=FBReaderJ-sources-$version.zip - -echo "" > data/formats/fb2/FBReaderVersion.ent -sed "s/@INTVERSION@/$intversion/" platform/android/AndroidManifest.xml.pattern | sed "s/@VERSION@/$version/" > platform/android/AndroidManifest.xml - -rm -rf $dir $archive -mkdir $dir -cp -r data icons src platform manifest.mf build.xml build_sources_archive.sh VERSION $dir -rm -rf `find $dir -name .svn` -zip -rq $archive $dir/* -rm -rf $dir diff --git a/data/formats/fb2/FBReaderVersion.ent b/data/formats/fb2/FBReaderVersion.ent index 2ca45276d..5e065325f 100644 --- a/data/formats/fb2/FBReaderVersion.ent +++ b/data/formats/fb2/FBReaderVersion.ent @@ -1 +1 @@ - + diff --git a/data/resources/application/en.xml b/data/resources/application/en.xml index 14b25ebb0..ebd925120 100644 --- a/data/resources/application/en.xml +++ b/data/resources/application/en.xml @@ -39,6 +39,8 @@ + + @@ -178,7 +180,7 @@ - + @@ -186,6 +188,9 @@ + + + diff --git a/data/resources/application/ru.xml b/data/resources/application/ru.xml index 7aa66e7ec..cf995b48a 100644 --- a/data/resources/application/ru.xml +++ b/data/resources/application/ru.xml @@ -37,6 +37,8 @@ + + @@ -176,7 +178,7 @@ - + @@ -184,6 +186,9 @@ + + + diff --git a/native/apps/DeflatingDecompressor/Application.mk b/native/apps/DeflatingDecompressor/Application.mk new file mode 100644 index 000000000..e47e87a03 --- /dev/null +++ b/native/apps/DeflatingDecompressor/Application.mk @@ -0,0 +1,2 @@ +APP_PROJECT_PATH := /Users/geometer/src/projects/FBReaderJ +APP_MODULES := DeflatingDecompressor diff --git a/native/apps/DeflatingDecompressor/project/libs/armeabi/libDeflatingDecompressor.so b/native/apps/DeflatingDecompressor/project/libs/armeabi/libDeflatingDecompressor.so new file mode 100755 index 000000000..593dd8b9b Binary files /dev/null and b/native/apps/DeflatingDecompressor/project/libs/armeabi/libDeflatingDecompressor.so differ diff --git a/native/sources/DeflatingDecompressor/Android.mk b/native/sources/DeflatingDecompressor/Android.mk new file mode 100644 index 000000000..9879dc3a1 --- /dev/null +++ b/native/sources/DeflatingDecompressor/Android.mk @@ -0,0 +1,10 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := DeflatingDecompressor +LOCAL_SRC_FILES := DeflatingDecompressor.cpp +#LOCAL_LDLIBS := -lz +LOCAL_ALLOW_UNDEFINED_SYMBOLS := true + +include $(BUILD_SHARED_LIBRARY) diff --git a/native/sources/DeflatingDecompressor/DeflatingDecompressor.cpp b/native/sources/DeflatingDecompressor/DeflatingDecompressor.cpp new file mode 100644 index 000000000..9db1d52fc --- /dev/null +++ b/native/sources/DeflatingDecompressor/DeflatingDecompressor.cpp @@ -0,0 +1,71 @@ +#include + +#include +#include + +#include + +#define SIZE 10 + +static jobject keys[SIZE] = { 0 }; +static z_stream* values[SIZE] = { 0 }; + +extern "C" +jboolean Java_org_amse_ys_zip_NativeDeflatingDecompressor_startInflating(JNIEnv *env, jobject thiz) { + int i; + for (i = 0; i < SIZE; ++i) { + if (keys[i] == 0) { + keys[i] = thiz; + values[i] = new z_stream; + memset(values[i], 0, sizeof(z_stream)); + inflateInit2(values[i], -MAX_WBITS); + return 1; + } + } + return 0; +} + +extern "C" +void Java_org_amse_ys_zip_NativeDeflatingDecompressor_endInflating(JNIEnv *env, jobject thiz) { + int i; + for (i = 0; i < SIZE; ++i) { + if (keys[i] == thiz) { + keys[i] = 0; + inflateEnd(values[i]); + delete values[i]; + values[i] = 0; + break; + } + } +} + +// returns ((used inLength) << 16) + utLength +extern "C" +jint Java_org_amse_ys_zip_NativeDeflatingDecompressor_inflate(JNIEnv *env, jobject thiz, jbyteArray in, jint inOffset, jint inLength, jbyteArray out) { + int i; + z_stream *stream = 0; + for (i = 0; i < SIZE; ++i) { + if (keys[i] == thiz) { + stream = values[i]; + break; + } + } + if (stream == 0) { + return 0; + } + + jbyte* inStart = env->GetByteArrayElements(in, 0); + jbyte* outStart = env->GetByteArrayElements(out, 0); + stream->next_in = (Bytef*)inStart + inOffset; + stream->avail_in = inLength; + stream->next_out = (Bytef*)outStart; + const int outLength = env->GetArrayLength(out); + stream->avail_out = outLength; + int code = inflate(stream, Z_SYNC_FLUSH); + env->ReleaseByteArrayElements(in, inStart, 0); + env->ReleaseByteArrayElements(out, outStart, 0); + if ((code == Z_OK) || (code == Z_STREAM_END)) { + return ((inLength - stream->avail_in) << 16) + outLength - stream->avail_out; + } + return 0; +} diff --git a/package_tool.sh b/package_tool.sh new file mode 100755 index 000000000..b8028c831 --- /dev/null +++ b/package_tool.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +updateVersionArg="--updateVersion" +buildSourceArchiveArg="--buildSourceArchive" + +printUsage() { + echo "usages:\n $0 $updateVersionArg [version]\n $0 $buildSourceArchiveArg [version]"; + exit; +} + +if [ $# -ne 1 -a $# -ne 2 ]; then + printUsage; +fi + +updateVersion() { + intversion=`echo $version | sed "s/\\./0/g" | sed -E "s/^0+//"` + echo "" > data/formats/fb2/FBReaderVersion.ent + sed "s/@INTVERSION@/$intversion/" platform/android/AndroidManifest.xml.pattern | sed "s/@VERSION@/$version/" > platform/android/AndroidManifest.xml +} + +buildSourceArchive() { + updateVersion + rm -rf $dir $archive + mkdir $dir + cp -r data icons src platform native manifest.mf build.xml $0 VERSION $dir + rm -rf `find $dir -name .svn` + zip -rq $archive $dir/* + rm -rf $dir +} + +if [ $# -eq 2 ]; then + version=$2; + echo $version > VERSION +else + version=`cat VERSION` +fi + +dir=FBReaderJ-sources-$version +archive=FBReaderJ-sources-$version.zip + + +case $1 in + $updateVersionArg) + updateVersion; + ;; + $buildSourceArchiveArg) + buildSourceArchive; + ;; + *) + printUsage; + ;; +esac diff --git a/platform/android/AndroidManifest.xml b/platform/android/AndroidManifest.xml index c5309c20a..b939716b2 100644 --- a/platform/android/AndroidManifest.xml +++ b/platform/android/AndroidManifest.xml @@ -1,6 +1,6 @@ - - + + diff --git a/platform/android/AndroidManifest.xml.pattern b/platform/android/AndroidManifest.xml.pattern index c1bb4dd02..aa33999b6 100644 --- a/platform/android/AndroidManifest.xml.pattern +++ b/platform/android/AndroidManifest.xml.pattern @@ -1,6 +1,6 @@ - + diff --git a/platform/android/build.xml b/platform/android/build.xml index c50379836..9893c942e 100644 --- a/platform/android/build.xml +++ b/platform/android/build.xml @@ -4,6 +4,8 @@ + + @@ -38,7 +40,7 @@ - + @@ -110,14 +112,6 @@ - - - Packaging java... - - - - - Packaging dex... @@ -127,10 +121,8 @@ - - - - + + diff --git a/platform/android/create_raw_resources.py b/platform/android/create_raw_resources.py index f44327b6d..08ceaea6c 100755 --- a/platform/android/create_raw_resources.py +++ b/platform/android/create_raw_resources.py @@ -10,6 +10,7 @@ data_dir_common = project_dir + "/data" application_icons_dir_common = project_dir + "/icons/application" tree_icons_dir_android = platform_dir + "/icons/tree" menu_icons_dir_android = platform_dir + "/icons/menu" +tabs_icons_dir_android = platform_dir + "/icons/tabs" text_search_icons_dir_android = platform_dir + "/icons/text_search" data_dir_android = platform_dir + "/data" @@ -38,6 +39,7 @@ clean_res_dir(drawable_res_dir) process_data_dir("data__", data_dir_common, raw_res_dir) process_data_dir("data__", data_dir_android, raw_res_dir) shutil.copyfile(application_icons_dir_common + "/48x48.png", drawable_res_dir + "/fbreader.png") -process_data_dir("tree_icon_", tree_icons_dir_android, drawable_res_dir, 0) -process_data_dir("menu_icon_", menu_icons_dir_android, drawable_res_dir, 0) +process_data_dir("", tree_icons_dir_android, drawable_res_dir, 0) +process_data_dir("", menu_icons_dir_android, drawable_res_dir, 0) +process_data_dir("", tabs_icons_dir_android, drawable_res_dir, 0) process_data_dir("text_search_", text_search_icons_dir_android, drawable_res_dir, 0) diff --git a/platform/android/data/default/menubar.xml b/platform/android/data/default/menubar.xml index 89eb18c65..aca798d7c 100644 --- a/platform/android/data/default/menubar.xml +++ b/platform/android/data/default/menubar.xml @@ -4,9 +4,11 @@ + + - + diff --git a/platform/android/icons/menu/bookInfo.png b/platform/android/icons/menu/bookInfo.png deleted file mode 100644 index 929a71d48..000000000 Binary files a/platform/android/icons/menu/bookInfo.png and /dev/null differ diff --git a/platform/android/icons/menu/bookmarks.png b/platform/android/icons/menu/bookmarks.png deleted file mode 100644 index 9df9113c3..000000000 Binary files a/platform/android/icons/menu/bookmarks.png and /dev/null differ diff --git a/platform/android/icons/menu/ic_menu_bookinfo.png b/platform/android/icons/menu/ic_menu_bookinfo.png new file mode 100644 index 000000000..65efaa3ba Binary files /dev/null and b/platform/android/icons/menu/ic_menu_bookinfo.png differ diff --git a/platform/android/icons/menu/ic_menu_bookmarks.png b/platform/android/icons/menu/ic_menu_bookmarks.png new file mode 100644 index 000000000..93bcb7943 Binary files /dev/null and b/platform/android/icons/menu/ic_menu_bookmarks.png differ diff --git a/platform/android/icons/menu/ic_menu_day.png b/platform/android/icons/menu/ic_menu_day.png new file mode 100755 index 000000000..74d080802 Binary files /dev/null and b/platform/android/icons/menu/ic_menu_day.png differ diff --git a/platform/android/icons/menu/ic_menu_library.png b/platform/android/icons/menu/ic_menu_library.png new file mode 100644 index 000000000..a8ce6cb5c Binary files /dev/null and b/platform/android/icons/menu/ic_menu_library.png differ diff --git a/platform/android/icons/menu/ic_menu_networksearch.png b/platform/android/icons/menu/ic_menu_networksearch.png new file mode 100644 index 000000000..d55d93b6d Binary files /dev/null and b/platform/android/icons/menu/ic_menu_networksearch.png differ diff --git a/platform/android/icons/menu/ic_menu_night.png b/platform/android/icons/menu/ic_menu_night.png new file mode 100644 index 000000000..1bbe767de Binary files /dev/null and b/platform/android/icons/menu/ic_menu_night.png differ diff --git a/platform/android/icons/menu/ic_menu_preferences.png b/platform/android/icons/menu/ic_menu_preferences.png new file mode 100644 index 000000000..b8e71412d Binary files /dev/null and b/platform/android/icons/menu/ic_menu_preferences.png differ diff --git a/platform/android/icons/menu/ic_menu_search.png b/platform/android/icons/menu/ic_menu_search.png new file mode 100644 index 000000000..94446db97 Binary files /dev/null and b/platform/android/icons/menu/ic_menu_search.png differ diff --git a/platform/android/icons/menu/ic_menu_toc.png b/platform/android/icons/menu/ic_menu_toc.png new file mode 100644 index 000000000..27197da3b Binary files /dev/null and b/platform/android/icons/menu/ic_menu_toc.png differ diff --git a/platform/android/icons/menu/library.png b/platform/android/icons/menu/library.png deleted file mode 100644 index e244cd29d..000000000 Binary files a/platform/android/icons/menu/library.png and /dev/null differ diff --git a/platform/android/icons/menu/networkSearch.png b/platform/android/icons/menu/networkSearch.png deleted file mode 100644 index f2e8fd003..000000000 Binary files a/platform/android/icons/menu/networkSearch.png and /dev/null differ diff --git a/platform/android/icons/menu/preferences.png b/platform/android/icons/menu/preferences.png deleted file mode 100644 index 5fd04b9c7..000000000 Binary files a/platform/android/icons/menu/preferences.png and /dev/null differ diff --git a/platform/android/icons/menu/search.png b/platform/android/icons/menu/search.png deleted file mode 100644 index 4fe48aba8..000000000 Binary files a/platform/android/icons/menu/search.png and /dev/null differ diff --git a/platform/android/icons/menu/toc.png b/platform/android/icons/menu/toc.png deleted file mode 100644 index d7c9227b0..000000000 Binary files a/platform/android/icons/menu/toc.png and /dev/null differ diff --git a/platform/android/icons/tabs/ic_tab_library_author.xml b/platform/android/icons/tabs/ic_tab_library_author.xml new file mode 100644 index 000000000..e09d3ee3c --- /dev/null +++ b/platform/android/icons/tabs/ic_tab_library_author.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/platform/android/icons/tabs/ic_tab_library_recent.xml b/platform/android/icons/tabs/ic_tab_library_recent.xml new file mode 100644 index 000000000..40e83408a --- /dev/null +++ b/platform/android/icons/tabs/ic_tab_library_recent.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/platform/android/icons/tabs/ic_tab_library_results.xml b/platform/android/icons/tabs/ic_tab_library_results.xml new file mode 100644 index 000000000..84002262d --- /dev/null +++ b/platform/android/icons/tabs/ic_tab_library_results.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/platform/android/icons/tabs/ic_tab_library_tag.xml b/platform/android/icons/tabs/ic_tab_library_tag.xml new file mode 100644 index 000000000..3530949e3 --- /dev/null +++ b/platform/android/icons/tabs/ic_tab_library_tag.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/platform/android/icons/tabs/ic_tab_selected_library_author.png b/platform/android/icons/tabs/ic_tab_selected_library_author.png new file mode 100644 index 000000000..4905dd1c4 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_selected_library_author.png differ diff --git a/platform/android/icons/tabs/ic_tab_selected_library_recent.png b/platform/android/icons/tabs/ic_tab_selected_library_recent.png new file mode 100644 index 000000000..8a30a4189 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_selected_library_recent.png differ diff --git a/platform/android/icons/tabs/ic_tab_selected_library_results.png b/platform/android/icons/tabs/ic_tab_selected_library_results.png new file mode 100644 index 000000000..50b328e81 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_selected_library_results.png differ diff --git a/platform/android/icons/tabs/ic_tab_selected_library_tag.png b/platform/android/icons/tabs/ic_tab_selected_library_tag.png new file mode 100644 index 000000000..1f2c90561 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_selected_library_tag.png differ diff --git a/platform/android/icons/tabs/ic_tab_unselected_library_author.png b/platform/android/icons/tabs/ic_tab_unselected_library_author.png new file mode 100644 index 000000000..c092d4737 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_unselected_library_author.png differ diff --git a/platform/android/icons/tabs/ic_tab_unselected_library_recent.png b/platform/android/icons/tabs/ic_tab_unselected_library_recent.png new file mode 100644 index 000000000..f830e2570 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_unselected_library_recent.png differ diff --git a/platform/android/icons/tabs/ic_tab_unselected_library_results.png b/platform/android/icons/tabs/ic_tab_unselected_library_results.png new file mode 100644 index 000000000..5975477b6 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_unselected_library_results.png differ diff --git a/platform/android/icons/tabs/ic_tab_unselected_library_tag.png b/platform/android/icons/tabs/ic_tab_unselected_library_tag.png new file mode 100644 index 000000000..1c0dacca2 Binary files /dev/null and b/platform/android/icons/tabs/ic_tab_unselected_library_tag.png differ diff --git a/platform/android/icons/tree/group_closed.png b/platform/android/icons/tree/group_closed.png deleted file mode 100644 index 0225c658d..000000000 Binary files a/platform/android/icons/tree/group_closed.png and /dev/null differ diff --git a/platform/android/icons/tree/group_empty.png b/platform/android/icons/tree/group_empty.png deleted file mode 100644 index b8897dc56..000000000 Binary files a/platform/android/icons/tree/group_empty.png and /dev/null differ diff --git a/platform/android/icons/tree/group_open.png b/platform/android/icons/tree/group_open.png deleted file mode 100644 index 3a8ed9a43..000000000 Binary files a/platform/android/icons/tree/group_open.png and /dev/null differ diff --git a/platform/android/icons/tree/ic_list_buy.png b/platform/android/icons/tree/ic_list_buy.png new file mode 100644 index 000000000..866161529 Binary files /dev/null and b/platform/android/icons/tree/ic_list_buy.png differ diff --git a/platform/android/icons/tree/ic_list_download.png b/platform/android/icons/tree/ic_list_download.png new file mode 100644 index 000000000..2ba14a6d6 Binary files /dev/null and b/platform/android/icons/tree/ic_list_download.png differ diff --git a/platform/android/icons/tree/ic_list_flag.png b/platform/android/icons/tree/ic_list_flag.png new file mode 100644 index 000000000..b0022728d Binary files /dev/null and b/platform/android/icons/tree/ic_list_flag.png differ diff --git a/platform/android/icons/tree/ic_list_group_closed.png b/platform/android/icons/tree/ic_list_group_closed.png new file mode 100644 index 000000000..689992bbc Binary files /dev/null and b/platform/android/icons/tree/ic_list_group_closed.png differ diff --git a/platform/android/icons/tree/ic_list_group_empty.png b/platform/android/icons/tree/ic_list_group_empty.png new file mode 100644 index 000000000..02ec2a97f Binary files /dev/null and b/platform/android/icons/tree/ic_list_group_empty.png differ diff --git a/platform/android/icons/tree/ic_list_group_open.png b/platform/android/icons/tree/ic_list_group_open.png new file mode 100644 index 000000000..43ff2ad59 Binary files /dev/null and b/platform/android/icons/tree/ic_list_group_open.png differ diff --git a/platform/android/icons/tree/plus.png b/platform/android/icons/tree/ic_list_plus.png similarity index 100% rename from platform/android/icons/tree/plus.png rename to platform/android/icons/tree/ic_list_plus.png diff --git a/platform/android/res/layout/library_tree_item.xml b/platform/android/res/layout/library_tree_item.xml index b2932a33f..4d317930c 100644 --- a/platform/android/res/layout/library_tree_item.xml +++ b/platform/android/res/layout/library_tree_item.xml @@ -11,7 +11,7 @@ android:id="@+id/library_tree_item_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingTop="5dip" + android:paddingTop="10dip" /> path = uri.getPathSegments(); @@ -71,7 +71,7 @@ public class BookDownloader extends Activity { requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.downloader); - ourProgressBar = (ProgressBar)findViewById(android.R.id.progress); + myProgressBar = (ProgressBar)findViewById(android.R.id.progress); final Intent intent = getIntent(); final Uri uri = intent.getData(); @@ -101,8 +101,8 @@ public class BookDownloader extends Activity { return; } - ourFileName = path.get(path.size() - 1); - final File fileFile = new File(dirFile, ourFileName); + myFileName = path.get(path.size() - 1); + final File fileFile = new File(dirFile, myFileName); if (fileFile.exists()) { if (!fileFile.isFile()) { // TODO: error message @@ -124,16 +124,16 @@ public class BookDownloader extends Activity { startFileDownload(uri.toString(), fileFile); } - if (ourFileLength <= 0) { - ourProgressBar.setIndeterminate(true); + if (myFileLength <= 0) { + myProgressBar.setIndeterminate(true); } else { - ourProgressBar.setIndeterminate(false); - ourProgressBar.setMax(ourFileLength); - ourProgressBar.setProgress(ourDownloadedPart); + myProgressBar.setIndeterminate(false); + myProgressBar.setMax(myFileLength); + myProgressBar.setProgress(myDownloadedPart); } final TextView textView = (TextView)findViewById(R.id.downloadertext); - textView.setText(ZLDialogManager.getWaitMessageText("downloadingFile").replace("%s", ourFileName)); + textView.setText(ZLDialogManager.getWaitMessageText("downloadingFile").replace("%s", myFileName)); } private void runFBReader(final File file) { @@ -159,12 +159,12 @@ public class BookDownloader extends Activity { try { final URL url = new URL(uriString); final URLConnection connection = url.openConnection(); - ourFileLength = connection.getContentLength(); - if (ourFileLength > 0) { - ourProgressBar.setIndeterminate(false); - ourProgressBar.setMax(ourFileLength); - ourProgressBar.setProgress(0); - ourDownloadedPart = 0; + myFileLength = connection.getContentLength(); + if (myFileLength > 0) { + myProgressBar.setIndeterminate(false); + myProgressBar.setMax(myFileLength); + myProgressBar.setProgress(0); + myDownloadedPart = 0; } final HttpURLConnection httpConnection = (HttpURLConnection)connection; final int response = httpConnection.getResponseCode(); @@ -178,8 +178,8 @@ public class BookDownloader extends Activity { if (size <= 0) { break; } - ourDownloadedPart += size; - ourProgressBar.setProgress(ourDownloadedPart); + myDownloadedPart += size; + myProgressBar.setProgress(myDownloadedPart); outStream.write(buffer, 0, size); } inStream.close(); @@ -191,7 +191,7 @@ public class BookDownloader extends Activity { // TODO: error message; remove file, don't start FBReader } handler.sendEmptyMessage(0); - ourFileLength = -1; + myFileLength = -1; } }).start(); } diff --git a/platform/android/src/org/geometerplus/android/fbreader/BookmarksActivity.java b/platform/android/src/org/geometerplus/android/fbreader/BookmarksActivity.java index e99a5eca4..0bf2e8c7d 100644 --- a/platform/android/src/org/geometerplus/android/fbreader/BookmarksActivity.java +++ b/platform/android/src/org/geometerplus/android/fbreader/BookmarksActivity.java @@ -123,7 +123,7 @@ public class BookmarksActivity extends TabActivity implements MenuItem.OnMenuIte myResource.getResource("menu").getResource("search").getValue() ); item.setOnMenuItemClickListener(this); - item.setIcon(R.drawable.menu_icon_search); + item.setIcon(R.drawable.ic_menu_search); return true; } @@ -355,7 +355,7 @@ mainLoop: final Bookmark bookmark = getItem(position); if (bookmark == null) { imageView.setVisibility(View.VISIBLE); - imageView.setImageResource(R.drawable.tree_icon_plus); + imageView.setImageResource(R.drawable.ic_list_plus); textView.setText(ZLResource.resource("bookmarksView").getResource("new").getValue()); bookTitleView.setVisibility(View.GONE); } else { @@ -368,16 +368,6 @@ mainLoop: bookTitleView.setText(bookmark.getBookTitle()); } } - /* - ((ImageView)view.findViewById(R.id.bookmark_item_icon)).setImageResource( - (bookmark != null) ? R.drawable.tree_icon_strut : R.drawable.tree_icon_plus - ); - ((TextView)view.findViewById(R.id.bookmark_item_text)).setText( - (bookmark != null) ? - bookmark.getText() : - ZLResource.resource("bookmarksView").getResource("new").getValue() - ); - */ return view; } diff --git a/platform/android/src/org/geometerplus/android/fbreader/LibraryTabActivity.java b/platform/android/src/org/geometerplus/android/fbreader/LibraryTabActivity.java index 2cf8fde10..1ebfcbb42 100644 --- a/platform/android/src/org/geometerplus/android/fbreader/LibraryTabActivity.java +++ b/platform/android/src/org/geometerplus/android/fbreader/LibraryTabActivity.java @@ -43,11 +43,11 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt private final ZLResource myResource = ZLResource.resource("libraryView"); private Book myCurrentBook; - private ListView createTab(String tag, int id) { + private ListView createTab(String tag, int viewId, int iconId) { final TabHost host = getTabHost(); final String label = myResource.getResource(tag).getValue(); - host.addTab(host.newTabSpec(tag).setIndicator(label).setContent(id)); - return (ListView)findViewById(id); + host.addTab(host.newTabSpec(tag).setIndicator(label, getResources().getDrawable(iconId)).setContent(viewId)); + return (ListView)findViewById(viewId); } @Override @@ -62,9 +62,9 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt final TabHost host = getTabHost(); LayoutInflater.from(this).inflate(R.layout.library, host.getTabContentView(), true); - new LibraryAdapter(createTab("byAuthor", R.id.by_author), Library.Instance().byAuthor(), false); - new LibraryAdapter(createTab("byTag", R.id.by_tag), Library.Instance().byTag(), false); - new LibraryAdapter(createTab("recent", R.id.recent), Library.Instance().recentBooks(), true); + new LibraryAdapter(createTab("byAuthor", R.id.by_author, R.drawable.ic_tab_library_author), Library.Instance().byAuthor(), Type.TREE); + new LibraryAdapter(createTab("byTag", R.id.by_tag, R.drawable.ic_tab_library_tag), Library.Instance().byTag(), Type.TREE); + new LibraryAdapter(createTab("recent", R.id.recent, R.drawable.ic_tab_library_recent), Library.Instance().recentBooks(), Type.FLAT); findViewById(R.id.search_results).setVisibility(View.GONE); host.setCurrentTabByTag(mySelectedTabOption.getValue()); @@ -74,7 +74,7 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt void showSearchResultsTab(LibraryTree tree) { if (mySearchResultsAdapter == null) { mySearchResultsAdapter = - new LibraryAdapter(createTab("searchResults", R.id.search_results), tree, true); + new LibraryAdapter(createTab("searchResults", R.id.search_results, R.drawable.ic_tab_library_results), tree, Type.FLAT); } else { mySearchResultsAdapter.resetTree(tree); } @@ -108,8 +108,8 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); - addMenuItem(menu, 1, "localSearch", R.drawable.menu_icon_search); - addMenuItem(menu, 2, "networkSearch", R.drawable.menu_icon_networksearch).setEnabled(false); + addMenuItem(menu, 1, "localSearch", R.drawable.ic_menu_search); + addMenuItem(menu, 2, "networkSearch", R.drawable.ic_menu_networksearch).setEnabled(false); return true; } @@ -137,17 +137,22 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt return true; } + interface Type { + int TREE = 0; + int FLAT = 1; + int NETWORK = 2; + } + private final class LibraryAdapter extends ZLTreeAdapter { private final LibraryTree myLibraryTree; - private final boolean myIsFlat; + + private final int myType; - LibraryAdapter(ListView view, LibraryTree tree, boolean isFlat) { + LibraryAdapter(ListView view, LibraryTree tree, int type) { super(view, tree); myLibraryTree = tree; - myIsFlat = isFlat; - if (!isFlat) { - selectItem(findFirstSelectedItem()); - } + myType = type; + selectItem(findFirstSelectedItem()); } @Override @@ -186,10 +191,26 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt view.setBackgroundColor(0); } final ImageView iconView = (ImageView)view.findViewById(R.id.library_tree_item_icon); - if (myIsFlat) { - iconView.setVisibility(View.GONE); - } else { - setIcon(iconView, tree); + switch (myType) { + case Type.FLAT: + iconView.setVisibility(View.GONE); + break; + case Type.TREE: + setIcon(iconView, tree); + break; + case Type.NETWORK: + switch (position % 3) { + case 0: + iconView.setImageResource(R.drawable.ic_list_buy); + break; + case 1: + iconView.setImageResource(R.drawable.ic_list_download); + break; + case 2: + iconView.setImageResource(R.drawable.ic_list_flag); + break; + } + break; } ((TextView)view.findViewById(R.id.library_tree_item_name)).setText(tree.getName()); ((TextView)view.findViewById(R.id.library_tree_item_childrenlist)).setText(tree.getSecondString()); diff --git a/platform/android/src/org/geometerplus/android/fbreader/ZLTreeAdapter.java b/platform/android/src/org/geometerplus/android/fbreader/ZLTreeAdapter.java index 421946856..c9324b9a5 100644 --- a/platform/android/src/org/geometerplus/android/fbreader/ZLTreeAdapter.java +++ b/platform/android/src/org/geometerplus/android/fbreader/ZLTreeAdapter.java @@ -180,12 +180,12 @@ abstract class ZLTreeAdapter extends BaseAdapter implements AdapterView.OnItemCl protected final void setIcon(ImageView imageView, ZLTree tree) { if (tree.hasChildren()) { if (isOpen(tree)) { - imageView.setImageResource(R.drawable.tree_icon_group_open); + imageView.setImageResource(R.drawable.ic_list_group_open); } else { - imageView.setImageResource(R.drawable.tree_icon_group_closed); + imageView.setImageResource(R.drawable.ic_list_group_closed); } } else { - imageView.setImageResource(R.drawable.tree_icon_group_empty); + imageView.setImageResource(R.drawable.ic_list_group_empty); } imageView.setPadding(25 * (tree.Level - 1), imageView.getPaddingTop(), 0, imageView.getPaddingBottom()); } diff --git a/platform/android/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java b/platform/android/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java index ed5ff1d23..d8dc97b90 100644 --- a/platform/android/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java +++ b/platform/android/src/org/geometerplus/zlibrary/ui/android/application/ZLAndroidApplicationWindow.java @@ -52,7 +52,7 @@ public final class ZLAndroidApplicationWindow extends ZLApplicationWindow { protected void processItem(ZLApplication.Menubar.PlainItem item) { MenuItem menuItem = myMenuStack.peek().add(0, myItemCount++, Menu.NONE, item.Name); try { - final String fieldName = "menu_icon_" + item.ActionId.toLowerCase(); + final String fieldName = "ic_menu_" + item.ActionId.toLowerCase(); menuItem.setIcon(R.drawable.class.getField(fieldName).getInt(null)); } catch (NoSuchFieldException e) { } catch (IllegalAccessException e) { diff --git a/src/org/amse/ys/zip/AbstractDeflatingDecompressor.java b/src/org/amse/ys/zip/AbstractDeflatingDecompressor.java new file mode 100644 index 000000000..e00d41ac2 --- /dev/null +++ b/src/org/amse/ys/zip/AbstractDeflatingDecompressor.java @@ -0,0 +1,5 @@ +package org.amse.ys.zip; + +abstract class AbstractDeflatingDecompressor extends Decompressor { + abstract void reset(MyBufferedInputStream inputStream, LocalFileHeader header); +} diff --git a/src/org/amse/ys/zip/Decompressor.java b/src/org/amse/ys/zip/Decompressor.java index 001517c72..b91830061 100644 --- a/src/org/amse/ys/zip/Decompressor.java +++ b/src/org/amse/ys/zip/Decompressor.java @@ -13,12 +13,12 @@ public abstract class Decompressor { protected Decompressor() { } - private static Queue ourDeflators = new LinkedList(); + private static Queue ourDeflators = new LinkedList(); static void storeDecompressor(Decompressor decompressor) { - if (decompressor instanceof DeflatingDecompressor) { + if (decompressor instanceof AbstractDeflatingDecompressor) { synchronized (ourDeflators) { - ourDeflators.add((DeflatingDecompressor)decompressor); + ourDeflators.add((AbstractDeflatingDecompressor)decompressor); } } } @@ -30,12 +30,15 @@ public abstract class Decompressor { case 8: synchronized (ourDeflators) { if (!ourDeflators.isEmpty()) { - DeflatingDecompressor decompressor = ourDeflators.poll(); + AbstractDeflatingDecompressor decompressor = ourDeflators.poll(); decompressor.reset(is, header); return decompressor; } } - return new DeflatingDecompressor(is, header); + return + NativeDeflatingDecompressor.INITIALIZED + ? new NativeDeflatingDecompressor(is, header) + : new DeflatingDecompressor(is, header); default: throw new ZipException("Unsupported method of compression"); } diff --git a/src/org/amse/ys/zip/DeflatingDecompressor.java b/src/org/amse/ys/zip/DeflatingDecompressor.java index f12ec772a..d9929470f 100644 --- a/src/org/amse/ys/zip/DeflatingDecompressor.java +++ b/src/org/amse/ys/zip/DeflatingDecompressor.java @@ -2,7 +2,7 @@ package org.amse.ys.zip; import java.io.*; -public class DeflatingDecompressor extends Decompressor { +public class DeflatingDecompressor extends AbstractDeflatingDecompressor { private static final int ST_HEADER = 1; private static final int ST_NO_COMPRESSION = 2; private static final int ST_FIXED_CODES = 3; @@ -54,6 +54,7 @@ public class DeflatingDecompressor extends Decompressor { myReadInBlock = 0; } + @Override public int available() { return myHeader.getUncompressedSize() - myCurrentPosition; } @@ -98,6 +99,7 @@ public class DeflatingDecompressor extends Decompressor { private static final int MAX_LEN = CircularBuffer.DICTIONARY_LENGTH / 2; + @Override public int read(byte b[], int off, int len) throws IOException { int i = 0; int available = myOutputBuffer.available(); @@ -126,6 +128,7 @@ public class DeflatingDecompressor extends Decompressor { return (i > 0) ? i : -1; } + @Override public int read() throws IOException { myCurrentPosition++; diff --git a/src/org/amse/ys/zip/MyBufferedInputStream.java b/src/org/amse/ys/zip/MyBufferedInputStream.java index 30fecb9c4..293ec0a89 100644 --- a/src/org/amse/ys/zip/MyBufferedInputStream.java +++ b/src/org/amse/ys/zip/MyBufferedInputStream.java @@ -30,6 +30,25 @@ final class MyBufferedInputStream extends InputStream { return myCurrentPosition; } + public int read(byte[] b, int off, int len) throws IOException { + int ready = (len < myBytesReady) ? len : myBytesReady; + if (ready > 0) { + System.arraycopy(myBuffer, myPositionInBuffer, b, off, ready); + len -= ready; + myBytesReady -= ready; + myPositionInBuffer += ready; + off += ready; + } + if (len > 0) { + final int ready2 = myFileInputStream.read(b, off, len); + if (ready2 >= 0) { + ready += ready2; + } + } + myCurrentPosition += ready; + return (ready > 0) ? ready : -1; + } + public int read() throws IOException { myCurrentPosition++; if (myBytesReady <= 0) { @@ -94,8 +113,8 @@ final class MyBufferedInputStream extends InputStream { } } - public void backSkip(int n) { - throw new RuntimeException("back skip not implemented"); + public void backSkip(int n) throws IOException { + throw new IOException("Back skip is not implemented"); } public void setPosition(int position) throws IOException { diff --git a/src/org/amse/ys/zip/NativeDeflatingDecompressor.java b/src/org/amse/ys/zip/NativeDeflatingDecompressor.java new file mode 100644 index 000000000..646b31f89 --- /dev/null +++ b/src/org/amse/ys/zip/NativeDeflatingDecompressor.java @@ -0,0 +1,126 @@ +package org.amse.ys.zip; + +import java.io.*; + +public class NativeDeflatingDecompressor extends AbstractDeflatingDecompressor { + public static final boolean INITIALIZED; + static { + boolean ini; + try { + System.loadLibrary("DeflatingDecompressor"); + ini = true; + } catch (Throwable t) { + ini = false; + } + INITIALIZED = ini; + } + + // common variables + private MyBufferedInputStream myStream; + private int myCompressedAvailable; + private int myAvailable; + + private static final int IN_BUFFER_SIZE = 2048; + private static final int OUT_BUFFER_SIZE = 32768; + + private final byte[] myInBuffer = new byte[IN_BUFFER_SIZE]; + private int myInBufferOffset; + private int myInBufferLength; + private final byte[] myOutBuffer = new byte[OUT_BUFFER_SIZE]; + private int myOutBufferOffset; + private int myOutBufferLength; + + public NativeDeflatingDecompressor(MyBufferedInputStream inputStream, LocalFileHeader header) { + super(); + reset(inputStream, header); + } + + void reset(MyBufferedInputStream inputStream, LocalFileHeader header) { + endInflating(); + + myStream = inputStream; + myCompressedAvailable = header.getCompressedSize(); + myAvailable = header.getUncompressedSize(); + + myInBufferOffset = IN_BUFFER_SIZE; + myInBufferLength = 0; + myOutBufferOffset = OUT_BUFFER_SIZE; + myOutBufferLength = 0; + + System.err.println(startInflating()); + } + + @Override + public int available() { + return myAvailable; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (myAvailable <= 0) { + return -1; + } + if (len > myAvailable) { + len = myAvailable; + } + for (int toFill = len; toFill > 0; ) { + if (myOutBufferLength == 0) { + fillOutBuffer(); + } + if (myOutBufferLength == 0) { + throw new IOException("cannot read from zip"); + } + final int ready = (toFill < myOutBufferLength) ? toFill : myOutBufferLength; + System.arraycopy(myOutBuffer, myOutBufferOffset, b, off, ready); + off += ready; + myOutBufferOffset += ready; + toFill -= ready; + myOutBufferLength -= ready; + } + myAvailable -= len; + return len; + } + + @Override + public int read() throws IOException { + if (myAvailable <= 0) { + return -1; + } + if (myOutBufferLength == 0) { + fillOutBuffer(); + } + if (myOutBufferLength == 0) { + throw new IOException("cannot read from zip"); + } + --myAvailable; + --myOutBufferLength; + return myOutBuffer[myOutBufferOffset++]; + } + + private void fillOutBuffer() throws IOException { + while (myOutBufferLength == 0) { + if (myInBufferLength == 0) { + myInBufferOffset = 0; + final int toRead = (myCompressedAvailable < IN_BUFFER_SIZE) ? myCompressedAvailable : IN_BUFFER_SIZE; + if (myStream.read(myInBuffer, 0, toRead) != toRead) { + throw new IOException("cannot read from base stream"); + } + myInBufferLength = toRead; + myCompressedAvailable -= toRead; + } + final int code = inflate(myInBuffer, myInBufferOffset, myInBufferLength, myOutBuffer); + if (code == 0) { + throw new IOException("cannot read from base stream"); + } + myInBufferOffset += code >> 16; + myInBufferLength -= code >> 16; + myOutBufferOffset = 0; + myOutBufferLength = code & 0x0FFFF; + System.err.println(myInBufferLength + ":" + myOutBufferLength + ":" + myAvailable); + } + } + + private native boolean startInflating(); + private native void endInflating(); + private native int inflate(byte[] in, int inOffset, int inLength, byte[] out); +} diff --git a/src/org/amse/ys/zip/ZipInputStream.java b/src/org/amse/ys/zip/ZipInputStream.java index 0d4c3a9fa..8de4d8302 100644 --- a/src/org/amse/ys/zip/ZipInputStream.java +++ b/src/org/amse/ys/zip/ZipInputStream.java @@ -18,10 +18,12 @@ class ZipInputStream extends InputStream { myDecompressor = Decompressor.init(myBaseStream, header); } + @Override public int available() { return myDecompressor.available(); } + @Override public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); @@ -35,6 +37,7 @@ class ZipInputStream extends InputStream { return myDecompressor.read(b, off, len); } + @Override public int read() throws IOException { return myDecompressor.read(); } diff --git a/src/org/geometerplus/fbreader/bookmodel/BookModel.java b/src/org/geometerplus/fbreader/bookmodel/BookModel.java index 51b9b423e..6fe862e06 100644 --- a/src/org/geometerplus/fbreader/bookmodel/BookModel.java +++ b/src/org/geometerplus/fbreader/bookmodel/BookModel.java @@ -36,21 +36,25 @@ public final class BookModel { return null; } BookModel model = new BookModel(book); + //android.os.Debug.startMethodTracing("bookReadingLT", 1 << 25); + //final boolean code = plugin.readModel(model); + //android.os.Debug.stopMethodTracing(); + //if (code) { if (plugin.readModel(model)) { return model; } return null; } + private final ZLImageMap myImageMap = new ZLImageMap(); + public final Book Book; - public final ZLTextModel BookTextModel = new ZLTextPlainModel(null, 1024, 65536, "/sdcard/Books/.FBReader", "cache"); + public final ZLTextModel BookTextModel = new ZLTextWritablePlainModel(null, 1024, 65536, "/sdcard/Books/.FBReader", "cache", myImageMap); public final TOCTree TOCTree = new TOCTree(); private final HashMap myFootnotes = new HashMap(); - private final HashMap myInternalHyperlinks = new HashMap(); + private final HashMap myInternalHyperlinks = new HashMap(); - private final ZLImageMap myImageMap = new ZLImageMap(); - public class Label { public final ZLTextModel Model; public final int ParagraphIndex; @@ -68,7 +72,7 @@ public final class BookModel { public ZLTextModel getFootnoteModel(String id) { ZLTextModel model = myFootnotes.get(id); if (model == null) { - model = new ZLTextPlainModel(id, 8, 2048, "/sdcard/Books/.FBReader", "cache" + myFootnotes.size()); + model = new ZLTextWritablePlainModel(id, 8, 2048, "/sdcard/Books/.FBReader", "cache" + myFootnotes.size(), myImageMap); myFootnotes.put(id, model); } return model; @@ -79,22 +83,9 @@ public final class BookModel { } public Label getLabel(String id) { - return (Label)myInternalHyperlinks.get(id); + return myInternalHyperlinks.get(id); } - //tmp - public ZLTextParagraph getParagraphByLink(String link) { - Label label = (Label)myInternalHyperlinks.get(link); - if (label != null) { - return label.Model.getParagraph(label.ParagraphIndex); - } - return null; - } - - public ZLImageMap getImageMap() { - return myImageMap; - } - void addImage(String id, ZLImage image) { myImageMap.put(id, image); } diff --git a/src/org/geometerplus/fbreader/bookmodel/BookReader.java b/src/org/geometerplus/fbreader/bookmodel/BookReader.java index f3b49aef3..d9be8a984 100644 --- a/src/org/geometerplus/fbreader/bookmodel/BookReader.java +++ b/src/org/geometerplus/fbreader/bookmodel/BookReader.java @@ -82,12 +82,14 @@ public class BookReader { } } + /* public final void addControl(ZLTextForcedControlEntry entry) { if (myTextParagraphExists) { flushTextBufferToParagraph(); myCurrentTextModel.addControl(entry); } } + */ public final void pushKind(byte kind) { byte[] stack = myKindStack; @@ -369,11 +371,11 @@ public class BookReader { mySectionContainsRegularContents = true; if (myTextParagraphExists) { flushTextBufferToParagraph(); - textModel.addImage(ref, Model.getImageMap(), vOffset); + textModel.addImage(ref, vOffset); } else { beginParagraph(ZLTextParagraph.Kind.TEXT_PARAGRAPH); textModel.addControl(FBTextKind.IMAGE, true); - textModel.addImage(ref, Model.getImageMap(), vOffset); + textModel.addImage(ref, vOffset); textModel.addControl(FBTextKind.IMAGE, false); endParagraph(); } diff --git a/src/org/geometerplus/fbreader/fbreader/ActionCode.java b/src/org/geometerplus/fbreader/fbreader/ActionCode.java index cad23d67d..9c9145d20 100644 --- a/src/org/geometerplus/fbreader/fbreader/ActionCode.java +++ b/src/org/geometerplus/fbreader/fbreader/ActionCode.java @@ -26,10 +26,15 @@ public interface ActionCode { String SHOW_BOOK_INFO = "bookInfo"; String SHOW_CONTENTS = "toc"; String SHOW_BOOKMARKS = "bookmarks"; + + String SWITCH_TO_NIGHT_PROFILE = "night"; + String SWITCH_TO_DAY_PROFILE = "day"; + String SEARCH = "search"; String FIND_PREVIOUS = "findPrevious"; String FIND_NEXT = "findNext"; String CLEAR_FIND_RESULTS = "clearFindResults"; + String VOLUME_KEY_SCROLL_FORWARD = "volumeKeyScrollForward"; String VOLUME_KEY_SCROLL_BACKWARD = "volumeKeyScrollBackward"; String TRACKBALL_SCROLL_FORWARD = "trackballScrollForward"; diff --git a/src/org/geometerplus/fbreader/fbreader/CancelAction.java b/src/org/geometerplus/fbreader/fbreader/CancelAction.java index 9dabfdb40..9f9b47f2c 100644 --- a/src/org/geometerplus/fbreader/fbreader/CancelAction.java +++ b/src/org/geometerplus/fbreader/fbreader/CancelAction.java @@ -25,8 +25,8 @@ class CancelAction extends FBAction { } public void run() { - if (Reader.getMode() != FBReader.ViewMode.BOOK_TEXT) { - Reader.restorePreviousMode(); + if (Reader.getCurrentView() != Reader.BookTextView) { + Reader.showBookTextView(); } else { Reader.closeWindow(); } diff --git a/src/org/geometerplus/fbreader/fbreader/ColorProfile.java b/src/org/geometerplus/fbreader/fbreader/ColorProfile.java index d1a407cb5..c15363772 100644 --- a/src/org/geometerplus/fbreader/fbreader/ColorProfile.java +++ b/src/org/geometerplus/fbreader/fbreader/ColorProfile.java @@ -25,6 +25,9 @@ import org.geometerplus.zlibrary.core.util.ZLColor; import org.geometerplus.zlibrary.core.options.*; public class ColorProfile { + public static final String DAY = "defaultLight"; + public static final String NIGHT = "defaultDark"; + private static final ArrayList ourNames = new ArrayList(); private static final HashMap ourProfiles = new HashMap(); @@ -32,8 +35,8 @@ public class ColorProfile { if (ourNames.isEmpty()) { final int size = new ZLIntegerOption("Colors", "NumberOfSchemes", 0).getValue(); if (size == 0) { - ourNames.add("defaultLight"); - ourNames.add("defaultDark"); + ourNames.add(DAY); + ourNames.add(NIGHT); } else for (int i = 0; i < size; ++i) { ourNames.add(new ZLStringOption("Colors", "Scheme" + i, "").getValue()); } @@ -52,7 +55,7 @@ public class ColorProfile { public final ZLColorOption BackgroundOption; public final ZLColorOption SelectionBackgroundOption; - public final ZLColorOption HighlightedTextOption; + public final ZLColorOption HighlightingOption; public final ZLColorOption RegularTextOption; public final ZLColorOption HyperlinkTextOption; @@ -60,30 +63,30 @@ public class ColorProfile { this(name); BackgroundOption.setValue(base.BackgroundOption.getValue()); SelectionBackgroundOption.setValue(base.SelectionBackgroundOption.getValue()); - HighlightedTextOption.setValue(base.HighlightedTextOption.getValue()); + HighlightingOption.setValue(base.HighlightingOption.getValue()); RegularTextOption.setValue(base.RegularTextOption.getValue()); HyperlinkTextOption.setValue(base.HyperlinkTextOption.getValue()); } private ColorProfile(String name) { - if ("defaultDark".equals(name)) { + if (NIGHT.equals(name)) { BackgroundOption = new ZLColorOption("Colors", name + ":Background", new ZLColor(0, 0, 0)); SelectionBackgroundOption = new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194)); - HighlightedTextOption = - new ZLColorOption("Colors", name + ":SelectedText", new ZLColor(45, 105, 192)); + HighlightingOption = + new ZLColorOption("Colors", name + ":Highlighting", new ZLColor(96, 96, 128)); RegularTextOption = new ZLColorOption("Colors", name + ":Text", new ZLColor(192, 192, 192)); HyperlinkTextOption = - new ZLColorOption("Colors", name + ":Hyperlink", new ZLColor(45, 105, 192)); + new ZLColorOption("Colors", name + ":Hyperlink", new ZLColor(60, 142, 224)); } else { BackgroundOption = new ZLColorOption("Colors", name + ":Background", new ZLColor(255, 255, 255)); SelectionBackgroundOption = new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194)); - HighlightedTextOption = - new ZLColorOption("Colors", name + ":SelectedText", new ZLColor(60, 139, 255)); + HighlightingOption = + new ZLColorOption("Colors", name + ":Highlighting", new ZLColor(255, 192, 128)); RegularTextOption = new ZLColorOption("Colors", name + ":Text", new ZLColor(0, 0, 0)); HyperlinkTextOption = diff --git a/src/org/geometerplus/fbreader/fbreader/FBReader.java b/src/org/geometerplus/fbreader/fbreader/FBReader.java index 164753f8a..4ce07c819 100644 --- a/src/org/geometerplus/fbreader/fbreader/FBReader.java +++ b/src/org/geometerplus/fbreader/fbreader/FBReader.java @@ -41,12 +41,6 @@ import org.geometerplus.fbreader.library.Book; import org.geometerplus.fbreader.library.Bookmark; public final class FBReader extends ZLApplication { - static interface ViewMode { - int UNDEFINED = 0; - int BOOK_TEXT = 1 << 0; - int FOOTNOTE = 1 << 1; - }; - public final ZLStringOption BookSearchPatternOption = new ZLStringOption("BookSearch", "Pattern", ""); public final ZLStringOption TextSearchPatternOption = @@ -70,16 +64,13 @@ public final class FBReader extends ZLApplication { new ZLBooleanOption("Options", "IsSelectionEnabled", true); final ZLStringOption ColorProfileOption = - new ZLStringOption("Options", "ColorProfile", "defaultLight"); + new ZLStringOption("Options", "ColorProfile", ColorProfile.DAY); private final ZLKeyBindings myBindings0 = new ZLKeyBindings("Keys"); private final ZLKeyBindings myBindings90 = new ZLKeyBindings("Keys90"); private final ZLKeyBindings myBindings180 = new ZLKeyBindings("Keys180"); private final ZLKeyBindings myBindings270 = new ZLKeyBindings("Keys270"); - private int myMode = ViewMode.UNDEFINED; - private int myPreviousMode = ViewMode.BOOK_TEXT; - public final FBView BookTextView; final FBView FootnoteView; @@ -122,10 +113,13 @@ public final class FBReader extends ZLApplication { //addAction(ActionCode.CLEAR_SELECTION, new DummyAction(this)); addAction(ActionCode.FOLLOW_HYPERLINK, new FollowHyperlinkAction(this)); + addAction(ActionCode.SWITCH_TO_DAY_PROFILE, new SwitchProfileAction(this, ColorProfile.DAY)); + addAction(ActionCode.SWITCH_TO_NIGHT_PROFILE, new SwitchProfileAction(this, ColorProfile.NIGHT)); + BookTextView = new FBView(this); FootnoteView = new FBView(this); - setMode(ViewMode.BOOK_TEXT); + setView(BookTextView); } public void initWindow() { @@ -156,7 +150,7 @@ public final class FBReader extends ZLApplication { public ColorProfile getColorProfile() { if (myColorProfile == null) { - myColorProfile = ColorProfile.get(ColorProfileOption.getValue()); + myColorProfile = ColorProfile.get(getColorProfileName()); } return myColorProfile; } @@ -193,35 +187,6 @@ public final class FBReader extends ZLApplication { return (FBView)getCurrentView(); } - int getMode() { - return myMode; - } - - void setMode(int mode) { - if (mode == myMode) { - return; - } - - myPreviousMode = myMode; - myMode = mode; - - switch (mode) { - case ViewMode.BOOK_TEXT: - setView(BookTextView); - break; - case ViewMode.FOOTNOTE: - setView(FootnoteView); - break; - default: - break; - } - } - - void restorePreviousMode() { - setMode(myPreviousMode); - myPreviousMode = ViewMode.BOOK_TEXT; - } - void tryOpenFootnote(String id) { if (Model != null) { BookModel.Label label = Model.getLabel(id); @@ -230,7 +195,7 @@ public final class FBReader extends ZLApplication { BookTextView.gotoPosition(label.ParagraphIndex, 0, 0); } else { FootnoteView.setModel(label.Model); - setMode(ViewMode.FOOTNOTE); + setView(FootnoteView); FootnoteView.gotoPosition(label.ParagraphIndex, 0, 0); } repaintView(); @@ -264,7 +229,7 @@ public final class FBReader extends ZLApplication { BookTextView.setModel(Model.BookTextModel); BookTextView.gotoPosition(book.getStoredPosition()); if (bookmark == null) { - setMode(ViewMode.BOOK_TEXT); + setView(BookTextView); } else { gotoBookmark(bookmark); } @@ -278,17 +243,17 @@ public final class FBReader extends ZLApplication { final String modelId = bookmark.getModelId(); if (modelId == null) { BookTextView.gotoPosition(bookmark); - setMode(ViewMode.BOOK_TEXT); + setView(BookTextView); } else { FootnoteView.setModel(Model.getFootnoteModel(modelId)); FootnoteView.gotoPosition(bookmark); - setMode(ViewMode.FOOTNOTE); + setView(FootnoteView); } repaintView(); } public void showBookTextView() { - setMode(ViewMode.BOOK_TEXT); + setView(BookTextView); } private Book createBookForFile(ZLFile file) { diff --git a/src/org/geometerplus/fbreader/fbreader/FBView.java b/src/org/geometerplus/fbreader/fbreader/FBView.java index d43331904..554ba72fd 100644 --- a/src/org/geometerplus/fbreader/fbreader/FBView.java +++ b/src/org/geometerplus/fbreader/fbreader/FBView.java @@ -215,30 +215,37 @@ public final class FBView extends ZLTextView { return true; } + @Override public int getLeftMargin() { return myReader.LeftMarginOption.getValue(); } + @Override public int getRightMargin() { return myReader.RightMarginOption.getValue(); } + @Override public int getTopMargin() { return myReader.TopMarginOption.getValue(); } + @Override public int getBottomMargin() { return myReader.BottomMarginOption.getValue(); } + @Override public ZLColor getBackgroundColor() { return myReader.getColorProfile().BackgroundOption.getValue(); } + @Override public ZLColor getSelectedBackgroundColor() { return myReader.getColorProfile().SelectionBackgroundOption.getValue(); } + @Override public ZLColor getTextColor(byte hyperlinkType) { final ColorProfile profile = myReader.getColorProfile(); switch (hyperlinkType) { @@ -251,8 +258,9 @@ public final class FBView extends ZLTextView { } } - public ZLColor getHighlightedTextColor() { - return myReader.getColorProfile().HighlightedTextOption.getValue(); + @Override + public ZLColor getHighlightingColor() { + return myReader.getColorProfile().HighlightingOption.getValue(); } protected boolean isSelectionEnabled() { diff --git a/src/org/geometerplus/fbreader/fbreader/ScrollToHomeAction.java b/src/org/geometerplus/fbreader/fbreader/ScrollToHomeAction.java index a0865ccda..abd559f03 100644 --- a/src/org/geometerplus/fbreader/fbreader/ScrollToHomeAction.java +++ b/src/org/geometerplus/fbreader/fbreader/ScrollToHomeAction.java @@ -25,7 +25,7 @@ class ScrollToHomeAction extends FBAction { } public boolean isVisible() { - return Reader.getMode() == FBReader.ViewMode.BOOK_TEXT; + return Reader.getCurrentView() == Reader.BookTextView; } public boolean isEnabled() { diff --git a/src/org/geometerplus/fbreader/fbreader/SetModeAction.java b/src/org/geometerplus/fbreader/fbreader/SwitchProfileAction.java similarity index 71% rename from src/org/geometerplus/fbreader/fbreader/SetModeAction.java rename to src/org/geometerplus/fbreader/fbreader/SwitchProfileAction.java index 13c0f3aaa..711f8e135 100644 --- a/src/org/geometerplus/fbreader/fbreader/SetModeAction.java +++ b/src/org/geometerplus/fbreader/fbreader/SwitchProfileAction.java @@ -19,21 +19,22 @@ package org.geometerplus.fbreader.fbreader; -class SetModeAction extends FBAction { - SetModeAction(FBReader fbreader, int modeToSet, int visibleInModes) { +import org.geometerplus.zlibrary.core.dialogs.ZLDialogManager; + +class SwitchProfileAction extends FBAction { + private String myProfileName; + + SwitchProfileAction(FBReader fbreader, String profileName) { super(fbreader); - myModeToSet = modeToSet; - myVisibleInModes = visibleInModes; + myProfileName = profileName; } public boolean isVisible() { - return (Reader.getMode() & myVisibleInModes) != 0; + return !myProfileName.equals(Reader.getColorProfileName()); } public void run() { - Reader.setMode(myModeToSet); + Reader.setColorProfileName(myProfileName); + Reader.repaintView(); } - - private final int myModeToSet; - private final int myVisibleInModes; } diff --git a/src/org/geometerplus/fbreader/formats/plucker/PluckerBookReader.java b/src/org/geometerplus/fbreader/formats/plucker/PluckerBookReader.java index f8d10300d..9024c3253 100644 --- a/src/org/geometerplus/fbreader/formats/plucker/PluckerBookReader.java +++ b/src/org/geometerplus/fbreader/formats/plucker/PluckerBookReader.java @@ -40,7 +40,7 @@ public class PluckerBookReader extends BookReader { private String myConvertedTextBuffer; private boolean myParagraphStarted = false; private boolean myBufferIsEmpty; - private ZLTextForcedControlEntry myForcedEntry; + //private ZLTextForcedControlEntry myForcedEntry; private final ArrayList/* >*/ myDelayedControls = new ArrayList(); private final ArrayList/* */myDelayedHyperlinks = new ArrayList(); private short myCompressionVersion; @@ -59,7 +59,7 @@ public class PluckerBookReader extends BookReader { //System.out.println(filePath + " " + encoding); myFont = FontType.FT_REGULAR; myCharBuffer = new char[65535]; - myForcedEntry = null; + //myForcedEntry = null; } public boolean readDocument() { @@ -319,9 +319,9 @@ public class PluckerBookReader extends BookReader { myBufferIsEmpty = false; } safeEndParagraph(); - if (myForcedEntry != null) { - myForcedEntry = null; - } + //if (myForcedEntry != null) { + // myForcedEntry = null; + //} myDelayedControls.clear(); } @@ -351,24 +351,24 @@ public class PluckerBookReader extends BookReader { break; case 0x22: if (!myParagraphStarted) { - if (myForcedEntry == null) { - myForcedEntry = new ZLTextForcedControlEntry(); - } - myForcedEntry.setLeftIndent((short)ptr[cur + 1]); - myForcedEntry.setRightIndent((short)ptr[cur + 2]); + //if (myForcedEntry == null) { + // myForcedEntry = new ZLTextForcedControlEntry(); + //} + //myForcedEntry.setLeftIndent((short)ptr[cur + 1]); + //myForcedEntry.setRightIndent((short)ptr[cur + 2]); } break; case 0x29: if (!myParagraphStarted) { - if (myForcedEntry == null) { - myForcedEntry = new ZLTextForcedControlEntry(); - } - switch (ptr[cur + 1]) { - case 0: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_LEFT); break; - case 1: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_RIGHT); break; - case 2: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_CENTER); break; - case 3: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_JUSTIFY); break; - } + //if (myForcedEntry == null) { + // myForcedEntry = new ZLTextForcedControlEntry(); + //} + //switch (ptr[cur + 1]) { + // case 0: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_LEFT); break; + // case 1: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_RIGHT); break; + // case 2: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_CENTER); break; + // case 3: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_JUSTIFY); break; + //} } break; case 0x33: // just break line instead of horizontal rule (TODO: draw horizontal rule?) @@ -489,11 +489,11 @@ public class PluckerBookReader extends BookReader { Pair pit = (Pair)it.next(); addControl((Byte)pit.myFirst, (Boolean)pit.mySecond); } - if (myForcedEntry != null) { - addControl(myForcedEntry); - } else { + //if (myForcedEntry != null) { + // addControl(myForcedEntry); + //} else { addControl(FBTextKind.REGULAR, true); - } + //} for (Iterator it = myDelayedHyperlinks.iterator(); it.hasNext(); ) { addHyperlinkControl(FBTextKind.INTERNAL_HYPERLINK, (String)it.next()); } diff --git a/src/org/geometerplus/fbreader/optionsDialog/OptionsDialog.java b/src/org/geometerplus/fbreader/optionsDialog/OptionsDialog.java index 9e1162c42..7adaddae1 100644 --- a/src/org/geometerplus/fbreader/optionsDialog/OptionsDialog.java +++ b/src/org/geometerplus/fbreader/optionsDialog/OptionsDialog.java @@ -62,9 +62,9 @@ public class OptionsDialog { final String BACKGROUND = resource.getResource("background").getValue(); final ColorProfile profile = fbreader.getColorProfile(); builder.addOption(BACKGROUND, profile.BackgroundOption); + builder.addOption(resource.getResource("highlighting").getValue(), profile.HighlightingOption); builder.addOption(resource.getResource("text").getValue(), profile.RegularTextOption); builder.addOption(resource.getResource("hyperlink").getValue(), profile.HyperlinkTextOption); - builder.addOption(resource.getResource("highlighted").getValue(), profile.HighlightedTextOption); builder.setInitial(BACKGROUND); colorsTab.addOption(colorKey, builder.comboEntry()); colorsTab.addOption("", builder.colorEntry()); diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextForcedControlEntry.java b/src/org/geometerplus/zlibrary/text/model/ZLTextForcedControlEntry.java index 6a2562eb1..ce11359e3 100644 --- a/src/org/geometerplus/zlibrary/text/model/ZLTextForcedControlEntry.java +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextForcedControlEntry.java @@ -19,12 +19,12 @@ package org.geometerplus.zlibrary.text.model; -public class ZLTextForcedControlEntry { - private final static int SUPPORTS_LEFT_INDENT = 1 << 0; - private final static int SUPPORTS_RIGHT_INDENT = 1 << 1; - private final static int SUPPORTS_ALIGNMENT_TYPE = 1 << 2; +public final class ZLTextForcedControlEntry { + final static short SUPPORTS_LEFT_INDENT = 1 << 0; + final static short SUPPORTS_RIGHT_INDENT = 1 << 1; + final static short SUPPORTS_ALIGNMENT_TYPE = 1 << 2; - private int myMask; + private short myMask; private short myLeftIndent; private short myRightIndent; private byte myAlignmentType; @@ -32,6 +32,10 @@ public class ZLTextForcedControlEntry { public ZLTextForcedControlEntry() { } + short getMask() { + return myMask; + }; + public boolean isLeftIndentSupported() { return (myMask & SUPPORTS_LEFT_INDENT) == SUPPORTS_LEFT_INDENT; } diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java b/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java index 614edbc3e..ad17ea1e8 100644 --- a/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextPlainModel.java @@ -24,22 +24,22 @@ import org.geometerplus.zlibrary.core.util.*; import org.geometerplus.zlibrary.core.image.ZLImageMap; -public final class ZLTextPlainModel implements ZLTextWritableModel { - private final String myId; +public class ZLTextPlainModel implements ZLTextModel { + protected final String myId; - private int[] myStartEntryIndices; - private int[] myStartEntryOffsets; - private int[] myParagraphLengths; - private byte[] myParagraphKinds; + protected int[] myStartEntryIndices; + protected int[] myStartEntryOffsets; + protected int[] myParagraphLengths; + protected byte[] myParagraphKinds; - private final ArrayList myEntries = new ArrayList(); + protected int myParagraphsNumber; - int myParagraphsNumber; + protected final CharStorage myStorage; + protected final ArrayList myMarks = new ArrayList(); + protected char[] myCurrentDataBlock; + protected int myBlockOffset; - private final CharStorage myStorage; - private final ArrayList myMarks = new ArrayList(); - private char[] myCurrentDataBlock; - private int myBlockOffset; + protected final ZLImageMap myImageMap; final class EntryIteratorImpl implements ZLTextParagraph.EntryIterator { private int myCounter; @@ -59,6 +59,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { private String myHyperlinkId; private ZLImageEntry myImageEntry; + private ZLTextForcedControlEntry myForcedControlEntry; private short myFixedHSpaceLength; @@ -106,6 +107,10 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { return myImageEntry; } + public ZLTextForcedControlEntry getForcedControlEntry() { + return myForcedControlEntry; + } + public short getFixedHSpaceLength() { return myFixedHSpaceLength; } @@ -153,10 +158,11 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { } case ZLTextParagraph.Entry.IMAGE: { - final int entryAddress = - ((int)data[dataOffset++] << 16) + - (int)data[dataOffset++]; - myImageEntry = (ZLImageEntry)myEntries.get(entryAddress); + final short vOffset = (short)data[dataOffset++]; + final short len = (short)data[dataOffset++]; + final String id = new String(data, dataOffset, len); + dataOffset += len; + myImageEntry = new ZLImageEntry(myImageMap, id, vOffset); break; } case ZLTextParagraph.Entry.FIXED_HSPACE: @@ -164,11 +170,21 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { break; case ZLTextParagraph.Entry.FORCED_CONTROL: { - final int entryAddress = - ((int)data[dataOffset++] << 16) + - (int)data[dataOffset++]; - //entry = myEntries.get((int)code); - break; + final int mask = (int)data[dataOffset++]; + final ZLTextForcedControlEntry entry = new ZLTextForcedControlEntry(); + if ((mask & ZLTextForcedControlEntry.SUPPORTS_LEFT_INDENT) == + ZLTextForcedControlEntry.SUPPORTS_LEFT_INDENT) { + entry.setLeftIndent((short)data[dataOffset++]); + } + if ((mask & ZLTextForcedControlEntry.SUPPORTS_RIGHT_INDENT) == + ZLTextForcedControlEntry.SUPPORTS_RIGHT_INDENT) { + entry.setRightIndent((short)data[dataOffset++]); + } + if ((mask & ZLTextForcedControlEntry.SUPPORTS_ALIGNMENT_TYPE) == + ZLTextForcedControlEntry.SUPPORTS_ALIGNMENT_TYPE) { + entry.setAlignmentType((byte)data[dataOffset++]); + } + myForcedControlEntry = entry; } } ++myCounter; @@ -176,132 +192,29 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { } } - public ZLTextPlainModel(String id, int arraySize, int dataBlockSize, String directoryName, String extension) { + protected ZLTextPlainModel(String id, int arraySize, int dataBlockSize, String directoryName, String extension, ZLImageMap imageMap) { myId = id; myStartEntryIndices = new int[arraySize]; myStartEntryOffsets = new int[arraySize]; myParagraphLengths = new int[arraySize]; myParagraphKinds = new byte[arraySize]; myStorage = new CachedCharStorage(dataBlockSize, directoryName, extension); + myImageMap = imageMap; } - public String getId() { + public final String getId() { return myId; } - private void extend() { - final int size = myStartEntryIndices.length; - myStartEntryIndices = ZLArrayUtils.createCopy(myStartEntryIndices, size, size << 1); - myStartEntryOffsets = ZLArrayUtils.createCopy(myStartEntryOffsets, size, size << 1); - myParagraphLengths = ZLArrayUtils.createCopy(myParagraphLengths, size, size << 1); - myParagraphKinds = ZLArrayUtils.createCopy(myParagraphKinds, size, size << 1); - } - - public void createParagraph(byte kind) { - final int index = myParagraphsNumber++; - int[] startEntryIndices = myStartEntryIndices; - if (index == startEntryIndices.length) { - extend(); - startEntryIndices = myStartEntryIndices; - } - final int dataSize = myStorage.size(); - startEntryIndices[index] = (dataSize == 0) ? 0 : (dataSize - 1); - myStartEntryOffsets[index] = myBlockOffset; - myParagraphLengths[index] = 0; - myParagraphKinds[index] = kind; - } - - private char[] getDataBlock(int minimumLength) { - char[] block = myCurrentDataBlock; - if ((block == null) || (minimumLength > block.length - myBlockOffset)) { - if (block != null) { - myStorage.freezeLastBlock(); - } - block = myStorage.createNewBlock(minimumLength); - myCurrentDataBlock = block; - myBlockOffset = 0; - } - return block; - } - - public void addControl(byte textKind, boolean isStart) { - final char[] block = getDataBlock(2); - ++myParagraphLengths[myParagraphsNumber - 1]; - block[myBlockOffset++] = (char)ZLTextParagraph.Entry.CONTROL; - short kind = textKind; - if (isStart) { - kind += 0x0100; - } - block[myBlockOffset++] = (char)kind; - } - - public void addText(char[] text) { - addText(text, 0, text.length); - } - - public void addText(char[] text, int offset, int length) { - char[] block = getDataBlock(3 + length); - ++myParagraphLengths[myParagraphsNumber - 1]; - int blockOffset = myBlockOffset; - block[blockOffset++] = (char)ZLTextParagraph.Entry.TEXT; - block[blockOffset++] = (char)(length >> 16); - block[blockOffset++] = (char)length; - System.arraycopy(text, offset, block, blockOffset, length); - myBlockOffset = blockOffset + length; - } - - - public void addControl(ZLTextForcedControlEntry entry) { - final char[] block = getDataBlock(3); - ++myParagraphLengths[myParagraphsNumber - 1]; - block[myBlockOffset++] = (char)ZLTextParagraph.Entry.FORCED_CONTROL; - final int entryAddress = myEntries.size(); - block[myBlockOffset++] = (char)(entryAddress >> 16); - block[myBlockOffset++] = (char)entryAddress; - myEntries.add(entry); - } - - - public void addHyperlinkControl(byte textKind, byte hyperlinkType, String label) { - final short labelLength = (short)label.length(); - final char[] block = getDataBlock(3 + labelLength); - ++myParagraphLengths[myParagraphsNumber - 1]; - int blockOffset = myBlockOffset; - block[blockOffset++] = (char)ZLTextParagraph.Entry.CONTROL; - block[blockOffset++] = (char)((hyperlinkType << 9) + 0x0100 + textKind); - block[blockOffset++] = (char)labelLength; - label.getChars(0, labelLength, block, blockOffset); - myBlockOffset = blockOffset + labelLength; - } - - public void addImage(String id, ZLImageMap imageMap, short vOffset) { - final char[] block = getDataBlock(3); - ++myParagraphLengths[myParagraphsNumber - 1]; - final ArrayList entries = myEntries; - block[myBlockOffset++] = (char)ZLTextParagraph.Entry.IMAGE; - final int entryAddress = myEntries.size(); - block[myBlockOffset++] = (char)(entryAddress >> 16); - block[myBlockOffset++] = (char)entryAddress; - entries.add(new ZLImageEntry(imageMap, id, vOffset)); - } - - - public void addFixedHSpace(short length) { - final char[] block = getDataBlock(2); - ++myParagraphLengths[myParagraphsNumber - 1]; - block[myBlockOffset++] = (char)ZLTextParagraph.Entry.FIXED_HSPACE; - block[myBlockOffset++] = (char)length; - } - - public ZLTextMark getFirstMark() { + public final ZLTextMark getFirstMark() { return myMarks.isEmpty() ? null : myMarks.get(0); } - public ZLTextMark getLastMark() { + public final ZLTextMark getLastMark() { return myMarks.isEmpty() ? null : myMarks.get(myMarks.size() - 1); } - public ZLTextMark getNextMark(ZLTextMark position) { + public final ZLTextMark getNextMark(ZLTextMark position) { if (position == null) { return null; } @@ -317,7 +230,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { return mark; } - public ZLTextMark getPreviousMark(ZLTextMark position) { + public final ZLTextMark getPreviousMark(ZLTextMark position) { if (position == null) { return null; } @@ -333,7 +246,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { return mark; } - public int search(final String text, int startIndex, int endIndex, boolean ignoreCase) { + public final int search(final String text, int startIndex, int endIndex, boolean ignoreCase) { int count = 0; ZLSearchPattern pattern = new ZLSearchPattern(text, ignoreCase); myMarks.clear(); @@ -364,26 +277,26 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { return count; } - public ArrayList getMarks() { + public final ArrayList getMarks() { return myMarks; } - public void removeAllMarks() { + public final void removeAllMarks() { myMarks.clear(); } - public int getParagraphsNumber() { + public final int getParagraphsNumber() { return myParagraphsNumber; } - public ZLTextParagraph getParagraph(int index) { + public final ZLTextParagraph getParagraph(int index) { final byte kind = myParagraphKinds[index]; return (kind == ZLTextParagraph.Kind.TEXT_PARAGRAPH) ? new ZLTextParagraphImpl(this, index) : new ZLTextSpecialParagraphImpl(kind, this, index); } - public int getParagraphTextLength(int index) { + public final int getParagraphTextLength(int index) { int textLength = 0; int dataIndex = myStartEntryIndices[index]; int dataOffset = myStartEntryOffsets[index]; @@ -417,13 +330,16 @@ public final class ZLTextPlainModel implements ZLTextWritableModel { break; } case ZLTextParagraph.Entry.IMAGE: - dataOffset += 2; + dataOffset++; + dataOffset += (short)data[dataOffset++]; break; case ZLTextParagraph.Entry.FIXED_HSPACE: ++dataOffset; break; case ZLTextParagraph.Entry.FORCED_CONTROL: - dataOffset += 2; + for (int mask = (int)data[dataOffset++]; mask != 0; mask >>= 1) { + dataOffset += mask & 1; + } break; } } diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextWritableModel.java b/src/org/geometerplus/zlibrary/text/model/ZLTextWritableModel.java index e2fd1dfd5..5efdc96cc 100644 --- a/src/org/geometerplus/zlibrary/text/model/ZLTextWritableModel.java +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextWritableModel.java @@ -28,8 +28,8 @@ public interface ZLTextWritableModel extends ZLTextModel { void addText(char[] text); void addText(char[] text, int offset, int length); - void addControl(ZLTextForcedControlEntry entry); + //void addControl(ZLTextForcedControlEntry entry); void addHyperlinkControl(byte textKind, byte hyperlinkType, String id); - void addImage(String id, ZLImageMap imageMap, short vOffset); + void addImage(String id, short vOffset); void addFixedHSpace(short length); } diff --git a/src/org/geometerplus/zlibrary/text/model/ZLTextWritablePlainModel.java b/src/org/geometerplus/zlibrary/text/model/ZLTextWritablePlainModel.java new file mode 100644 index 000000000..63127a4e3 --- /dev/null +++ b/src/org/geometerplus/zlibrary/text/model/ZLTextWritablePlainModel.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2007-2009 Geometer Plus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +package org.geometerplus.zlibrary.text.model; + +import java.util.*; +import org.geometerplus.zlibrary.core.util.*; + +import org.geometerplus.zlibrary.core.image.ZLImageMap; + +public final class ZLTextWritablePlainModel extends ZLTextPlainModel implements ZLTextWritableModel { + public ZLTextWritablePlainModel(String id, int arraySize, int dataBlockSize, String directoryName, String extension, ZLImageMap imageMap) { + super(id, arraySize, dataBlockSize, directoryName, extension, imageMap); + } + + private void extend() { + final int size = myStartEntryIndices.length; + myStartEntryIndices = ZLArrayUtils.createCopy(myStartEntryIndices, size, size << 1); + myStartEntryOffsets = ZLArrayUtils.createCopy(myStartEntryOffsets, size, size << 1); + myParagraphLengths = ZLArrayUtils.createCopy(myParagraphLengths, size, size << 1); + myParagraphKinds = ZLArrayUtils.createCopy(myParagraphKinds, size, size << 1); + } + + public void createParagraph(byte kind) { + final int index = myParagraphsNumber++; + int[] startEntryIndices = myStartEntryIndices; + if (index == startEntryIndices.length) { + extend(); + startEntryIndices = myStartEntryIndices; + } + final int dataSize = myStorage.size(); + startEntryIndices[index] = (dataSize == 0) ? 0 : (dataSize - 1); + myStartEntryOffsets[index] = myBlockOffset; + myParagraphLengths[index] = 0; + myParagraphKinds[index] = kind; + } + + private char[] getDataBlock(int minimumLength) { + char[] block = myCurrentDataBlock; + if ((block == null) || (minimumLength > block.length - myBlockOffset)) { + if (block != null) { + myStorage.freezeLastBlock(); + } + block = myStorage.createNewBlock(minimumLength); + myCurrentDataBlock = block; + myBlockOffset = 0; + } + return block; + } + + public void addControl(byte textKind, boolean isStart) { + final char[] block = getDataBlock(2); + ++myParagraphLengths[myParagraphsNumber - 1]; + block[myBlockOffset++] = (char)ZLTextParagraph.Entry.CONTROL; + short kind = textKind; + if (isStart) { + kind += 0x0100; + } + block[myBlockOffset++] = (char)kind; + } + + public void addText(char[] text) { + addText(text, 0, text.length); + } + + public void addText(char[] text, int offset, int length) { + char[] block = getDataBlock(3 + length); + ++myParagraphLengths[myParagraphsNumber - 1]; + int blockOffset = myBlockOffset; + block[blockOffset++] = (char)ZLTextParagraph.Entry.TEXT; + block[blockOffset++] = (char)(length >> 16); + block[blockOffset++] = (char)length; + System.arraycopy(text, offset, block, blockOffset, length); + myBlockOffset = blockOffset + length; + } + + public void addControl(ZLTextForcedControlEntry entry) { + int len = 2; + for (int mask = entry.getMask(); mask != 0; mask >>= 1) { + len += mask & 1; + } + final char[] block = getDataBlock(len); + ++myParagraphLengths[myParagraphsNumber - 1]; + block[myBlockOffset++] = (char)ZLTextParagraph.Entry.FORCED_CONTROL; + block[myBlockOffset++] = (char)entry.getMask(); + if (entry.isLeftIndentSupported()) { + block[myBlockOffset++] = (char)entry.getLeftIndent(); + } + if (entry.isRightIndentSupported()) { + block[myBlockOffset++] = (char)entry.getRightIndent(); + } + if (entry.isAlignmentTypeSupported()) { + block[myBlockOffset++] = (char)entry.getAlignmentType(); + } + } + + public void addHyperlinkControl(byte textKind, byte hyperlinkType, String label) { + final short labelLength = (short)label.length(); + final char[] block = getDataBlock(3 + labelLength); + ++myParagraphLengths[myParagraphsNumber - 1]; + int blockOffset = myBlockOffset; + block[blockOffset++] = (char)ZLTextParagraph.Entry.CONTROL; + block[blockOffset++] = (char)((hyperlinkType << 9) + 0x0100 + textKind); + block[blockOffset++] = (char)labelLength; + label.getChars(0, labelLength, block, blockOffset); + myBlockOffset = blockOffset + labelLength; + } + + public void addImage(String id, short vOffset) { + final int len = id.length(); + final char[] block = getDataBlock(3 + len); + ++myParagraphLengths[myParagraphsNumber - 1]; + int blockOffset = myBlockOffset; + block[blockOffset++] = (char)ZLTextParagraph.Entry.IMAGE; + block[blockOffset++] = (char)vOffset; + block[blockOffset++] = (char)len; + id.getChars(0, len, block, blockOffset); + myBlockOffset = blockOffset + len; + } + + public void addFixedHSpace(short length) { + final char[] block = getDataBlock(2); + ++myParagraphLengths[myParagraphsNumber - 1]; + block[myBlockOffset++] = (char)ZLTextParagraph.Entry.FIXED_HSPACE; + block[myBlockOffset++] = (char)length; + } +} diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java index 2a84d114f..ff74f8ce7 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextView.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextView.java @@ -475,6 +475,13 @@ public abstract class ZLTextView extends ZLTextViewBase { context.drawImage(areaX, areaY, ((ZLTextImageElement)element).ImageData); } else if (element == ZLTextElement.HSpace) { final int cw = context.getSpaceWidth(); + /* + context.setFillColor(getHighlightingColor()); + context.fillRectangle( + area.XStart, areaY - context.getStringHeight(), + area.XEnd - 1, areaY + context.getDescent() + ); + */ for (int len = 0; len < area.XEnd - area.XStart; len += cw) { context.drawString(areaX + len, areaY, SPACE, 0, 1); } diff --git a/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java b/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java index 25bc3b063..f38f92cb4 100644 --- a/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java +++ b/src/org/geometerplus/zlibrary/text/view/ZLTextViewBase.java @@ -43,7 +43,7 @@ abstract class ZLTextViewBase extends ZLView { public abstract ZLColor getBackgroundColor(); public abstract ZLColor getSelectedBackgroundColor(); public abstract ZLColor getTextColor(byte hyperlinkType); - public abstract ZLColor getHighlightedTextColor(); + public abstract ZLColor getHighlightingColor(); int getTextAreaHeight() { return Context.getHeight() - getTopMargin() - getBottomMargin(); @@ -230,10 +230,12 @@ abstract class ZLTextViewBase extends ZLView { } if (markStart < length) { - context.setTextColor(getHighlightedTextColor()); + context.setFillColor(getHighlightingColor()); int endPos = Math.min(markStart + markLen, length); + final int endX = x + context.getStringWidth(str, offset + markStart, endPos - markStart); + context.fillRectangle(x, y - context.getStringHeight(), endX - 1, y + context.getDescent()); context.drawString(x, y, str, offset + markStart, endPos - markStart); - x += context.getStringWidth(str, offset + markStart, endPos - markStart); + x = endX; context.setTextColor(getTextColor(myTextStyle.Hyperlink.Type)); } pos = markStart + markLen;