1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 10:19:33 +02:00

new icon set

native unzip
new build script



git-svn-id: https://only.mawhrin.net/repos/FBReaderJ/trunk@990 6a642e6f-84f6-412e-ac94-c4a38d5a04b0
This commit is contained in:
Nikolay Pultsin 2009-06-30 08:11:39 +00:00
parent dfece0b383
commit b6970e1dc9
82 changed files with 735 additions and 369 deletions

View file

@ -1 +1 @@
0.5.7
0.5.8

View file

@ -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 "<!ENTITY FBReaderVersion \"$version\">" > 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

View file

@ -1 +1 @@
<!ENTITY FBReaderVersion "0.5.7">
<!ENTITY FBReaderVersion "0.5.8">

View file

@ -39,6 +39,8 @@
<node name="bookInfo" value="Book info"/>
<node name="library" value="Library"/>
<node name="toc" value="TOC"/>
<node name="day" value="Day"/>
<node name="night" value="Night"/>
<node name="navigate" value="Navigate">
<node name="toc" value="Table of Contents"/>
<node name="gotoHome" value="Go to Start of Document"/>
@ -178,7 +180,7 @@
<node name="selectionBackground" value="Selection Background"/>
<node name="text" value="Regular Text"/>
<node name="hyperlink" value="Hyperlink Text"/>
<node name="highlighted" value="Highlighted Text"/>
<node name="highlighting" value="Search Results Background"/>
</node>
</node>
</node>
@ -186,6 +188,9 @@
<node name="deleteBookBox">
<node name="message" value="The book file will be removed irreversibly. Are you sure?"/>
</node>
<node name="redownloadFileBox">
<node name="message" value="File already exists. Redownload?"/>
</node>
<node name="waitMessage">
<node name="downloadingFile" value="Downloading book %s"/>
<node name="search" value="Searching. Please, wait..."/>

View file

@ -37,6 +37,8 @@
<node name="preferences" value="Настройки"/>
<node name="bookInfo" value="О книге"/>
<node name="toc" value="Оглавление"/>
<node name="day" value="День"/>
<node name="night" value="Ночь"/>
<node name="library" value="Библиотека"/>
<node name="navigate" value="Переход">
<node name="gotoHome" value="В начало книги"/>
@ -176,7 +178,7 @@
<node name="selectionBackground" value="фона пометки"/>
<node name="text" value="обычного текста"/>
<node name="hyperlink" value="ссылки"/>
<node name="highlighted" value="подсвеченного текста"/>
<node name="highlighting" value="фона результатов поиска"/>
</node>
</node>
</node>
@ -184,6 +186,9 @@
<node name="deleteBookBox">
<node name="message" value="Файл книги будет удален необратимо. Продолжать?"/>
</node>
<node name="redownloadFileBox">
<node name="message" value="Файл уже есть на устройстве. Загрузить заново?"/>
</node>
<node name="waitMessage">
<node name="downloadingFile" value="Загужается книга %s"/>
<node name="search" value="Идет поиск. Подождите, пожалуйста..."/>

View file

@ -0,0 +1,2 @@
APP_PROJECT_PATH := /Users/geometer/src/projects/FBReaderJ
APP_MODULES := DeflatingDecompressor

View file

@ -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)

View file

@ -0,0 +1,71 @@
#include <jni.h>
#include <string.h>
#include <zlib.h>
#include <new>
#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;
}

52
package_tool.sh Executable file
View file

@ -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 "<!ENTITY FBReaderVersion \"$version\">" > 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

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="507" android:versionName="0.5.7">
<uses-sdk android:minSdkVersion="1"/>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="508" android:versionName="0.5.8">
<uses-sdk android:minSdkVersion="3"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:name="org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication" android:icon="@drawable/fbreader" android:label="FBReader">

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.geometerplus.zlibrary.ui.android" android:versionCode="@INTVERSION@" android:versionName="@VERSION@">
<uses-sdk android:minSdkVersion="1"/>
<uses-sdk android:minSdkVersion="3"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<application android:name="org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication" android:icon="@drawable/fbreader" android:label="FBReader">

View file

@ -4,6 +4,8 @@
<!-- property name="sdk-folder" value="/home/geometer/src/android_sdk_linux_m3-rc37a" / -->
<property name="sdk-folder" value="/Users/geometer/android-sdk-mac_x86-1.0_r1" />
<property name="android-tools" value="${sdk-folder}/tools" />
<property name="sdk-folder-1.5" value="/Users/geometer/android-sdk-mac_x86-1.5_r1" />
<property name="android-tools-1.5" value="${sdk-folder-1.5}/tools" />
<property name="project-dir" value="/Users/geometer/src/projects/FBReaderJ" />
<property name="platform-dir" value="${project-dir}/platform/android" />
@ -38,7 +40,7 @@
<property name="aapt" value="${android-tools}/aapt" />
<property name="dx" value="${android-tools}/dx" />
<property name="adb" value="${android-tools}/adb" />
<property name="apk-builder" value="${android-tools}/apkbuilder" />
<property name="apk-builder" value="${android-tools-1.5}/apkbuilder" />
<property name="android-jar" value="${sdk-folder}/android.jar" />
<!-- Rules -->
@ -110,14 +112,6 @@
</exec>
</target>
<!-- Put the project's .class files into the output package file. -->
<target name="package-java" depends="compile, package-res">
<echo>Packaging java...</echo>
<jar destfile="${out-package}" update="true">
<fileset dir = "${outdir-classes}"/>
</jar>
</target>
<!-- Put the project's .dex files into the output package file. -->
<target name="package-dex" depends="dex, package-res">
<echo>Packaging dex...</echo>
@ -127,10 +121,8 @@
<arg value="${resources-package}" />
<arg value="-f" />
<arg value="${intermediate-dex}" />
<arg value="-rf" />
<arg value="${project-dir}/src" />
<arg value="-rf" />
<arg value="${platform-dir}/src" />
<arg value="-nf" />
<arg value="${project-dir}/libs" />
</exec>
</target>

View file

@ -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)

View file

@ -4,9 +4,11 @@
<item id="toc"/>
<item id="bookmarks"/>
<item id="search"/>
<item id="night"/>
<item id="day"/>
<item id="preferences"/>
<item id="bookInfo"/>
<item id="preferences-old"/>
<item id="bookInfo"/>
<submenu id="navigate">
<item id="gotoHome"/>
<item id="gotoSectionStart"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_selected_library_author" />
<item android:drawable="@drawable/ic_tab_unselected_library_author" />
</selector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_selected_library_recent" />
<item android:drawable="@drawable/ic_tab_unselected_library_recent" />
</selector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_selected_library_results" />
<item android:drawable="@drawable/ic_tab_unselected_library_results" />
</selector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/ic_tab_selected_library_tag" />
<item android:drawable="@drawable/ic_tab_unselected_library_tag" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 272 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

View file

Before

Width:  |  Height:  |  Size: 298 B

After

Width:  |  Height:  |  Size: 298 B

Before After
Before After

View file

@ -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"
/>
<LinearLayout
android:layout_width="wrap_content"

View file

@ -40,10 +40,10 @@ import org.geometerplus.zlibrary.ui.android.library.ZLAndroidApplication;
import org.geometerplus.zlibrary.ui.android.R;
public class BookDownloader extends Activity {
private static ProgressBar ourProgressBar;
private static int ourFileLength = -1;
private static int ourDownloadedPart = 0;
private static String ourFileName = "";
private ProgressBar myProgressBar;
private int myFileLength = -1;
private int myDownloadedPart = 0;
private String myFileName = "";
public static boolean acceptsUri(Uri uri) {
final List<String> 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();
}

View file

@ -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;
}

View file

@ -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,18 +137,23 @@ 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;
LibraryAdapter(ListView view, LibraryTree tree, boolean isFlat) {
private final int myType;
LibraryAdapter(ListView view, LibraryTree tree, int type) {
super(view, tree);
myLibraryTree = tree;
myIsFlat = isFlat;
if (!isFlat) {
myType = type;
selectItem(findFirstSelectedItem());
}
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
@ -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) {
switch (myType) {
case Type.FLAT:
iconView.setVisibility(View.GONE);
} else {
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());

View file

@ -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());
}

View file

@ -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) {

View file

@ -0,0 +1,5 @@
package org.amse.ys.zip;
abstract class AbstractDeflatingDecompressor extends Decompressor {
abstract void reset(MyBufferedInputStream inputStream, LocalFileHeader header);
}

View file

@ -13,12 +13,12 @@ public abstract class Decompressor {
protected Decompressor() {
}
private static Queue<DeflatingDecompressor> ourDeflators = new LinkedList<DeflatingDecompressor>();
private static Queue<AbstractDeflatingDecompressor> ourDeflators = new LinkedList<AbstractDeflatingDecompressor>();
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");
}

View file

@ -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++;

View file

@ -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 {

View file

@ -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);
}

View file

@ -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();
}

View file

@ -36,20 +36,24 @@ 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<String,ZLTextModel> myFootnotes = new HashMap<String,ZLTextModel>();
private final HashMap myInternalHyperlinks = new HashMap();
private final ZLImageMap myImageMap = new ZLImageMap();
private final HashMap<String,Label> myInternalHyperlinks = new HashMap<String,Label>();
public class Label {
public final ZLTextModel Model;
@ -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,20 +83,7 @@ public final class BookModel {
}
public Label getLabel(String id) {
return (Label)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;
return myInternalHyperlinks.get(id);
}
void addImage(String id, ZLImage image) {

View file

@ -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();
}

View file

@ -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";

View file

@ -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();
}

View file

@ -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<String> ourNames = new ArrayList<String>();
private static final HashMap<String,ColorProfile> ourProfiles = new HashMap<String,ColorProfile>();
@ -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 =

View file

@ -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) {

View file

@ -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() {

View file

@ -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() {

View file

@ -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;
}

View file

@ -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/*<std::pair<FBTextKind,bool> >*/ myDelayedControls = new ArrayList();
private final ArrayList/*<std::string> */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());
}

View file

@ -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());

View file

@ -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;
}

View file

@ -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<ZLTextMark> myMarks = new ArrayList<ZLTextMark>();
protected char[] myCurrentDataBlock;
protected int myBlockOffset;
private final CharStorage myStorage;
private final ArrayList<ZLTextMark> myMarks = new ArrayList<ZLTextMark>();
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<ZLTextMark> 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;
}
}

View file

@ -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);
}

View file

@ -0,0 +1,143 @@
/*
* Copyright (C) 2007-2009 Geometer Plus <contact@geometerplus.com>
*
* 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;
}
}

View file

@ -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);
}

View file

@ -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;