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

View file

@ -37,6 +37,8 @@
<node name="preferences" value="Настройки"/> <node name="preferences" value="Настройки"/>
<node name="bookInfo" value="О книге"/> <node name="bookInfo" value="О книге"/>
<node name="toc" value="Оглавление"/> <node name="toc" value="Оглавление"/>
<node name="day" value="День"/>
<node name="night" value="Ночь"/>
<node name="library" value="Библиотека"/> <node name="library" value="Библиотека"/>
<node name="navigate" value="Переход"> <node name="navigate" value="Переход">
<node name="gotoHome" value="В начало книги"/> <node name="gotoHome" value="В начало книги"/>
@ -176,7 +178,7 @@
<node name="selectionBackground" value="фона пометки"/> <node name="selectionBackground" value="фона пометки"/>
<node name="text" value="обычного текста"/> <node name="text" value="обычного текста"/>
<node name="hyperlink" value="ссылки"/> <node name="hyperlink" value="ссылки"/>
<node name="highlighted" value="подсвеченного текста"/> <node name="highlighting" value="фона результатов поиска"/>
</node> </node>
</node> </node>
</node> </node>
@ -184,6 +186,9 @@
<node name="deleteBookBox"> <node name="deleteBookBox">
<node name="message" value="Файл книги будет удален необратимо. Продолжать?"/> <node name="message" value="Файл книги будет удален необратимо. Продолжать?"/>
</node> </node>
<node name="redownloadFileBox">
<node name="message" value="Файл уже есть на устройстве. Загрузить заново?"/>
</node>
<node name="waitMessage"> <node name="waitMessage">
<node name="downloadingFile" value="Загужается книга %s"/> <node name="downloadingFile" value="Загужается книга %s"/>
<node name="search" value="Идет поиск. Подождите, пожалуйста..."/> <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"?> <?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"> <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="1"/> <uses-sdk android:minSdkVersion="3"/>
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <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"> <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"?> <?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@"> <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.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <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"> <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="/home/geometer/src/android_sdk_linux_m3-rc37a" / -->
<property name="sdk-folder" value="/Users/geometer/android-sdk-mac_x86-1.0_r1" /> <property name="sdk-folder" value="/Users/geometer/android-sdk-mac_x86-1.0_r1" />
<property name="android-tools" value="${sdk-folder}/tools" /> <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="project-dir" value="/Users/geometer/src/projects/FBReaderJ" />
<property name="platform-dir" value="${project-dir}/platform/android" /> <property name="platform-dir" value="${project-dir}/platform/android" />
@ -38,7 +40,7 @@
<property name="aapt" value="${android-tools}/aapt" /> <property name="aapt" value="${android-tools}/aapt" />
<property name="dx" value="${android-tools}/dx" /> <property name="dx" value="${android-tools}/dx" />
<property name="adb" value="${android-tools}/adb" /> <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" /> <property name="android-jar" value="${sdk-folder}/android.jar" />
<!-- Rules --> <!-- Rules -->
@ -110,14 +112,6 @@
</exec> </exec>
</target> </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. --> <!-- Put the project's .dex files into the output package file. -->
<target name="package-dex" depends="dex, package-res"> <target name="package-dex" depends="dex, package-res">
<echo>Packaging dex...</echo> <echo>Packaging dex...</echo>
@ -127,10 +121,8 @@
<arg value="${resources-package}" /> <arg value="${resources-package}" />
<arg value="-f" /> <arg value="-f" />
<arg value="${intermediate-dex}" /> <arg value="${intermediate-dex}" />
<arg value="-rf" /> <arg value="-nf" />
<arg value="${project-dir}/src" /> <arg value="${project-dir}/libs" />
<arg value="-rf" />
<arg value="${platform-dir}/src" />
</exec> </exec>
</target> </target>

View file

@ -10,6 +10,7 @@ data_dir_common = project_dir + "/data"
application_icons_dir_common = project_dir + "/icons/application" application_icons_dir_common = project_dir + "/icons/application"
tree_icons_dir_android = platform_dir + "/icons/tree" tree_icons_dir_android = platform_dir + "/icons/tree"
menu_icons_dir_android = platform_dir + "/icons/menu" 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" text_search_icons_dir_android = platform_dir + "/icons/text_search"
data_dir_android = platform_dir + "/data" 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_common, raw_res_dir)
process_data_dir("data__", data_dir_android, 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") 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("", tree_icons_dir_android, drawable_res_dir, 0)
process_data_dir("menu_icon_", menu_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) 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="toc"/>
<item id="bookmarks"/> <item id="bookmarks"/>
<item id="search"/> <item id="search"/>
<item id="night"/>
<item id="day"/>
<item id="preferences"/> <item id="preferences"/>
<item id="bookInfo"/>
<item id="preferences-old"/> <item id="preferences-old"/>
<item id="bookInfo"/>
<submenu id="navigate"> <submenu id="navigate">
<item id="gotoHome"/> <item id="gotoHome"/>
<item id="gotoSectionStart"/> <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:id="@+id/library_tree_item_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="5dip" android:paddingTop="10dip"
/> />
<LinearLayout <LinearLayout
android:layout_width="wrap_content" 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; import org.geometerplus.zlibrary.ui.android.R;
public class BookDownloader extends Activity { public class BookDownloader extends Activity {
private static ProgressBar ourProgressBar; private ProgressBar myProgressBar;
private static int ourFileLength = -1; private int myFileLength = -1;
private static int ourDownloadedPart = 0; private int myDownloadedPart = 0;
private static String ourFileName = ""; private String myFileName = "";
public static boolean acceptsUri(Uri uri) { public static boolean acceptsUri(Uri uri) {
final List<String> path = uri.getPathSegments(); final List<String> path = uri.getPathSegments();
@ -71,7 +71,7 @@ public class BookDownloader extends Activity {
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.downloader); setContentView(R.layout.downloader);
ourProgressBar = (ProgressBar)findViewById(android.R.id.progress); myProgressBar = (ProgressBar)findViewById(android.R.id.progress);
final Intent intent = getIntent(); final Intent intent = getIntent();
final Uri uri = intent.getData(); final Uri uri = intent.getData();
@ -101,8 +101,8 @@ public class BookDownloader extends Activity {
return; return;
} }
ourFileName = path.get(path.size() - 1); myFileName = path.get(path.size() - 1);
final File fileFile = new File(dirFile, ourFileName); final File fileFile = new File(dirFile, myFileName);
if (fileFile.exists()) { if (fileFile.exists()) {
if (!fileFile.isFile()) { if (!fileFile.isFile()) {
// TODO: error message // TODO: error message
@ -124,16 +124,16 @@ public class BookDownloader extends Activity {
startFileDownload(uri.toString(), fileFile); startFileDownload(uri.toString(), fileFile);
} }
if (ourFileLength <= 0) { if (myFileLength <= 0) {
ourProgressBar.setIndeterminate(true); myProgressBar.setIndeterminate(true);
} else { } else {
ourProgressBar.setIndeterminate(false); myProgressBar.setIndeterminate(false);
ourProgressBar.setMax(ourFileLength); myProgressBar.setMax(myFileLength);
ourProgressBar.setProgress(ourDownloadedPart); myProgressBar.setProgress(myDownloadedPart);
} }
final TextView textView = (TextView)findViewById(R.id.downloadertext); 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) { private void runFBReader(final File file) {
@ -159,12 +159,12 @@ public class BookDownloader extends Activity {
try { try {
final URL url = new URL(uriString); final URL url = new URL(uriString);
final URLConnection connection = url.openConnection(); final URLConnection connection = url.openConnection();
ourFileLength = connection.getContentLength(); myFileLength = connection.getContentLength();
if (ourFileLength > 0) { if (myFileLength > 0) {
ourProgressBar.setIndeterminate(false); myProgressBar.setIndeterminate(false);
ourProgressBar.setMax(ourFileLength); myProgressBar.setMax(myFileLength);
ourProgressBar.setProgress(0); myProgressBar.setProgress(0);
ourDownloadedPart = 0; myDownloadedPart = 0;
} }
final HttpURLConnection httpConnection = (HttpURLConnection)connection; final HttpURLConnection httpConnection = (HttpURLConnection)connection;
final int response = httpConnection.getResponseCode(); final int response = httpConnection.getResponseCode();
@ -178,8 +178,8 @@ public class BookDownloader extends Activity {
if (size <= 0) { if (size <= 0) {
break; break;
} }
ourDownloadedPart += size; myDownloadedPart += size;
ourProgressBar.setProgress(ourDownloadedPart); myProgressBar.setProgress(myDownloadedPart);
outStream.write(buffer, 0, size); outStream.write(buffer, 0, size);
} }
inStream.close(); inStream.close();
@ -191,7 +191,7 @@ public class BookDownloader extends Activity {
// TODO: error message; remove file, don't start FBReader // TODO: error message; remove file, don't start FBReader
} }
handler.sendEmptyMessage(0); handler.sendEmptyMessage(0);
ourFileLength = -1; myFileLength = -1;
} }
}).start(); }).start();
} }

View file

@ -123,7 +123,7 @@ public class BookmarksActivity extends TabActivity implements MenuItem.OnMenuIte
myResource.getResource("menu").getResource("search").getValue() myResource.getResource("menu").getResource("search").getValue()
); );
item.setOnMenuItemClickListener(this); item.setOnMenuItemClickListener(this);
item.setIcon(R.drawable.menu_icon_search); item.setIcon(R.drawable.ic_menu_search);
return true; return true;
} }
@ -355,7 +355,7 @@ mainLoop:
final Bookmark bookmark = getItem(position); final Bookmark bookmark = getItem(position);
if (bookmark == null) { if (bookmark == null) {
imageView.setVisibility(View.VISIBLE); 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()); textView.setText(ZLResource.resource("bookmarksView").getResource("new").getValue());
bookTitleView.setVisibility(View.GONE); bookTitleView.setVisibility(View.GONE);
} else { } else {
@ -368,16 +368,6 @@ mainLoop:
bookTitleView.setText(bookmark.getBookTitle()); 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; return view;
} }

View file

@ -43,11 +43,11 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
private final ZLResource myResource = ZLResource.resource("libraryView"); private final ZLResource myResource = ZLResource.resource("libraryView");
private Book myCurrentBook; private Book myCurrentBook;
private ListView createTab(String tag, int id) { private ListView createTab(String tag, int viewId, int iconId) {
final TabHost host = getTabHost(); final TabHost host = getTabHost();
final String label = myResource.getResource(tag).getValue(); final String label = myResource.getResource(tag).getValue();
host.addTab(host.newTabSpec(tag).setIndicator(label).setContent(id)); host.addTab(host.newTabSpec(tag).setIndicator(label, getResources().getDrawable(iconId)).setContent(viewId));
return (ListView)findViewById(id); return (ListView)findViewById(viewId);
} }
@Override @Override
@ -62,9 +62,9 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
final TabHost host = getTabHost(); final TabHost host = getTabHost();
LayoutInflater.from(this).inflate(R.layout.library, host.getTabContentView(), true); 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("byAuthor", R.id.by_author, R.drawable.ic_tab_library_author), Library.Instance().byAuthor(), Type.TREE);
new LibraryAdapter(createTab("byTag", R.id.by_tag), Library.Instance().byTag(), false); 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), Library.Instance().recentBooks(), true); 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); findViewById(R.id.search_results).setVisibility(View.GONE);
host.setCurrentTabByTag(mySelectedTabOption.getValue()); host.setCurrentTabByTag(mySelectedTabOption.getValue());
@ -74,7 +74,7 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
void showSearchResultsTab(LibraryTree tree) { void showSearchResultsTab(LibraryTree tree) {
if (mySearchResultsAdapter == null) { if (mySearchResultsAdapter == null) {
mySearchResultsAdapter = 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 { } else {
mySearchResultsAdapter.resetTree(tree); mySearchResultsAdapter.resetTree(tree);
} }
@ -108,8 +108,8 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu); super.onCreateOptionsMenu(menu);
addMenuItem(menu, 1, "localSearch", R.drawable.menu_icon_search); addMenuItem(menu, 1, "localSearch", R.drawable.ic_menu_search);
addMenuItem(menu, 2, "networkSearch", R.drawable.menu_icon_networksearch).setEnabled(false); addMenuItem(menu, 2, "networkSearch", R.drawable.ic_menu_networksearch).setEnabled(false);
return true; return true;
} }
@ -137,17 +137,22 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
return true; return true;
} }
interface Type {
int TREE = 0;
int FLAT = 1;
int NETWORK = 2;
}
private final class LibraryAdapter extends ZLTreeAdapter { private final class LibraryAdapter extends ZLTreeAdapter {
private final LibraryTree myLibraryTree; 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); super(view, tree);
myLibraryTree = tree; myLibraryTree = tree;
myIsFlat = isFlat; myType = type;
if (!isFlat) { selectItem(findFirstSelectedItem());
selectItem(findFirstSelectedItem());
}
} }
@Override @Override
@ -186,10 +191,26 @@ public class LibraryTabActivity extends TabActivity implements MenuItem.OnMenuIt
view.setBackgroundColor(0); view.setBackgroundColor(0);
} }
final ImageView iconView = (ImageView)view.findViewById(R.id.library_tree_item_icon); final ImageView iconView = (ImageView)view.findViewById(R.id.library_tree_item_icon);
if (myIsFlat) { switch (myType) {
iconView.setVisibility(View.GONE); case Type.FLAT:
} else { iconView.setVisibility(View.GONE);
setIcon(iconView, tree); 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_name)).setText(tree.getName());
((TextView)view.findViewById(R.id.library_tree_item_childrenlist)).setText(tree.getSecondString()); ((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) { protected final void setIcon(ImageView imageView, ZLTree tree) {
if (tree.hasChildren()) { if (tree.hasChildren()) {
if (isOpen(tree)) { if (isOpen(tree)) {
imageView.setImageResource(R.drawable.tree_icon_group_open); imageView.setImageResource(R.drawable.ic_list_group_open);
} else { } else {
imageView.setImageResource(R.drawable.tree_icon_group_closed); imageView.setImageResource(R.drawable.ic_list_group_closed);
} }
} else { } 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()); 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) { protected void processItem(ZLApplication.Menubar.PlainItem item) {
MenuItem menuItem = myMenuStack.peek().add(0, myItemCount++, Menu.NONE, item.Name); MenuItem menuItem = myMenuStack.peek().add(0, myItemCount++, Menu.NONE, item.Name);
try { 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)); menuItem.setIcon(R.drawable.class.getField(fieldName).getInt(null));
} catch (NoSuchFieldException e) { } catch (NoSuchFieldException e) {
} catch (IllegalAccessException 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() { protected Decompressor() {
} }
private static Queue<DeflatingDecompressor> ourDeflators = new LinkedList<DeflatingDecompressor>(); private static Queue<AbstractDeflatingDecompressor> ourDeflators = new LinkedList<AbstractDeflatingDecompressor>();
static void storeDecompressor(Decompressor decompressor) { static void storeDecompressor(Decompressor decompressor) {
if (decompressor instanceof DeflatingDecompressor) { if (decompressor instanceof AbstractDeflatingDecompressor) {
synchronized (ourDeflators) { synchronized (ourDeflators) {
ourDeflators.add((DeflatingDecompressor)decompressor); ourDeflators.add((AbstractDeflatingDecompressor)decompressor);
} }
} }
} }
@ -30,12 +30,15 @@ public abstract class Decompressor {
case 8: case 8:
synchronized (ourDeflators) { synchronized (ourDeflators) {
if (!ourDeflators.isEmpty()) { if (!ourDeflators.isEmpty()) {
DeflatingDecompressor decompressor = ourDeflators.poll(); AbstractDeflatingDecompressor decompressor = ourDeflators.poll();
decompressor.reset(is, header); decompressor.reset(is, header);
return decompressor; return decompressor;
} }
} }
return new DeflatingDecompressor(is, header); return
NativeDeflatingDecompressor.INITIALIZED
? new NativeDeflatingDecompressor(is, header)
: new DeflatingDecompressor(is, header);
default: default:
throw new ZipException("Unsupported method of compression"); throw new ZipException("Unsupported method of compression");
} }

View file

@ -2,7 +2,7 @@ package org.amse.ys.zip;
import java.io.*; 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_HEADER = 1;
private static final int ST_NO_COMPRESSION = 2; private static final int ST_NO_COMPRESSION = 2;
private static final int ST_FIXED_CODES = 3; private static final int ST_FIXED_CODES = 3;
@ -54,6 +54,7 @@ public class DeflatingDecompressor extends Decompressor {
myReadInBlock = 0; myReadInBlock = 0;
} }
@Override
public int available() { public int available() {
return myHeader.getUncompressedSize() - myCurrentPosition; return myHeader.getUncompressedSize() - myCurrentPosition;
} }
@ -98,6 +99,7 @@ public class DeflatingDecompressor extends Decompressor {
private static final int MAX_LEN = CircularBuffer.DICTIONARY_LENGTH / 2; private static final int MAX_LEN = CircularBuffer.DICTIONARY_LENGTH / 2;
@Override
public int read(byte b[], int off, int len) throws IOException { public int read(byte b[], int off, int len) throws IOException {
int i = 0; int i = 0;
int available = myOutputBuffer.available(); int available = myOutputBuffer.available();
@ -126,6 +128,7 @@ public class DeflatingDecompressor extends Decompressor {
return (i > 0) ? i : -1; return (i > 0) ? i : -1;
} }
@Override
public int read() throws IOException { public int read() throws IOException {
myCurrentPosition++; myCurrentPosition++;

View file

@ -30,6 +30,25 @@ final class MyBufferedInputStream extends InputStream {
return myCurrentPosition; 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 { public int read() throws IOException {
myCurrentPosition++; myCurrentPosition++;
if (myBytesReady <= 0) { if (myBytesReady <= 0) {
@ -94,8 +113,8 @@ final class MyBufferedInputStream extends InputStream {
} }
} }
public void backSkip(int n) { public void backSkip(int n) throws IOException {
throw new RuntimeException("back skip not implemented"); throw new IOException("Back skip is not implemented");
} }
public void setPosition(int position) throws IOException { 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); myDecompressor = Decompressor.init(myBaseStream, header);
} }
@Override
public int available() { public int available() {
return myDecompressor.available(); return myDecompressor.available();
} }
@Override
public int read(byte b[], int off, int len) throws IOException { public int read(byte b[], int off, int len) throws IOException {
if (b == null) { if (b == null) {
throw new NullPointerException(); throw new NullPointerException();
@ -35,6 +37,7 @@ class ZipInputStream extends InputStream {
return myDecompressor.read(b, off, len); return myDecompressor.read(b, off, len);
} }
@Override
public int read() throws IOException { public int read() throws IOException {
return myDecompressor.read(); return myDecompressor.read();
} }

View file

@ -36,21 +36,25 @@ public final class BookModel {
return null; return null;
} }
BookModel model = new BookModel(book); 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)) { if (plugin.readModel(model)) {
return model; return model;
} }
return null; return null;
} }
private final ZLImageMap myImageMap = new ZLImageMap();
public final Book Book; 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(); public final TOCTree TOCTree = new TOCTree();
private final HashMap<String,ZLTextModel> myFootnotes = new HashMap<String,ZLTextModel>(); private final HashMap<String,ZLTextModel> myFootnotes = new HashMap<String,ZLTextModel>();
private final HashMap myInternalHyperlinks = new HashMap(); private final HashMap<String,Label> myInternalHyperlinks = new HashMap<String,Label>();
private final ZLImageMap myImageMap = new ZLImageMap();
public class Label { public class Label {
public final ZLTextModel Model; public final ZLTextModel Model;
public final int ParagraphIndex; public final int ParagraphIndex;
@ -68,7 +72,7 @@ public final class BookModel {
public ZLTextModel getFootnoteModel(String id) { public ZLTextModel getFootnoteModel(String id) {
ZLTextModel model = myFootnotes.get(id); ZLTextModel model = myFootnotes.get(id);
if (model == null) { 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); myFootnotes.put(id, model);
} }
return model; return model;
@ -79,22 +83,9 @@ public final class BookModel {
} }
public Label getLabel(String id) { 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) { void addImage(String id, ZLImage image) {
myImageMap.put(id, image); myImageMap.put(id, image);
} }

View file

@ -82,12 +82,14 @@ public class BookReader {
} }
} }
/*
public final void addControl(ZLTextForcedControlEntry entry) { public final void addControl(ZLTextForcedControlEntry entry) {
if (myTextParagraphExists) { if (myTextParagraphExists) {
flushTextBufferToParagraph(); flushTextBufferToParagraph();
myCurrentTextModel.addControl(entry); myCurrentTextModel.addControl(entry);
} }
} }
*/
public final void pushKind(byte kind) { public final void pushKind(byte kind) {
byte[] stack = myKindStack; byte[] stack = myKindStack;
@ -369,11 +371,11 @@ public class BookReader {
mySectionContainsRegularContents = true; mySectionContainsRegularContents = true;
if (myTextParagraphExists) { if (myTextParagraphExists) {
flushTextBufferToParagraph(); flushTextBufferToParagraph();
textModel.addImage(ref, Model.getImageMap(), vOffset); textModel.addImage(ref, vOffset);
} else { } else {
beginParagraph(ZLTextParagraph.Kind.TEXT_PARAGRAPH); beginParagraph(ZLTextParagraph.Kind.TEXT_PARAGRAPH);
textModel.addControl(FBTextKind.IMAGE, true); textModel.addControl(FBTextKind.IMAGE, true);
textModel.addImage(ref, Model.getImageMap(), vOffset); textModel.addImage(ref, vOffset);
textModel.addControl(FBTextKind.IMAGE, false); textModel.addControl(FBTextKind.IMAGE, false);
endParagraph(); endParagraph();
} }

View file

@ -26,10 +26,15 @@ public interface ActionCode {
String SHOW_BOOK_INFO = "bookInfo"; String SHOW_BOOK_INFO = "bookInfo";
String SHOW_CONTENTS = "toc"; String SHOW_CONTENTS = "toc";
String SHOW_BOOKMARKS = "bookmarks"; String SHOW_BOOKMARKS = "bookmarks";
String SWITCH_TO_NIGHT_PROFILE = "night";
String SWITCH_TO_DAY_PROFILE = "day";
String SEARCH = "search"; String SEARCH = "search";
String FIND_PREVIOUS = "findPrevious"; String FIND_PREVIOUS = "findPrevious";
String FIND_NEXT = "findNext"; String FIND_NEXT = "findNext";
String CLEAR_FIND_RESULTS = "clearFindResults"; String CLEAR_FIND_RESULTS = "clearFindResults";
String VOLUME_KEY_SCROLL_FORWARD = "volumeKeyScrollForward"; String VOLUME_KEY_SCROLL_FORWARD = "volumeKeyScrollForward";
String VOLUME_KEY_SCROLL_BACKWARD = "volumeKeyScrollBackward"; String VOLUME_KEY_SCROLL_BACKWARD = "volumeKeyScrollBackward";
String TRACKBALL_SCROLL_FORWARD = "trackballScrollForward"; String TRACKBALL_SCROLL_FORWARD = "trackballScrollForward";

View file

@ -25,8 +25,8 @@ class CancelAction extends FBAction {
} }
public void run() { public void run() {
if (Reader.getMode() != FBReader.ViewMode.BOOK_TEXT) { if (Reader.getCurrentView() != Reader.BookTextView) {
Reader.restorePreviousMode(); Reader.showBookTextView();
} else { } else {
Reader.closeWindow(); Reader.closeWindow();
} }

View file

@ -25,6 +25,9 @@ import org.geometerplus.zlibrary.core.util.ZLColor;
import org.geometerplus.zlibrary.core.options.*; import org.geometerplus.zlibrary.core.options.*;
public class ColorProfile { 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 ArrayList<String> ourNames = new ArrayList<String>();
private static final HashMap<String,ColorProfile> ourProfiles = new HashMap<String,ColorProfile>(); private static final HashMap<String,ColorProfile> ourProfiles = new HashMap<String,ColorProfile>();
@ -32,8 +35,8 @@ public class ColorProfile {
if (ourNames.isEmpty()) { if (ourNames.isEmpty()) {
final int size = new ZLIntegerOption("Colors", "NumberOfSchemes", 0).getValue(); final int size = new ZLIntegerOption("Colors", "NumberOfSchemes", 0).getValue();
if (size == 0) { if (size == 0) {
ourNames.add("defaultLight"); ourNames.add(DAY);
ourNames.add("defaultDark"); ourNames.add(NIGHT);
} else for (int i = 0; i < size; ++i) { } else for (int i = 0; i < size; ++i) {
ourNames.add(new ZLStringOption("Colors", "Scheme" + i, "").getValue()); ourNames.add(new ZLStringOption("Colors", "Scheme" + i, "").getValue());
} }
@ -52,7 +55,7 @@ public class ColorProfile {
public final ZLColorOption BackgroundOption; public final ZLColorOption BackgroundOption;
public final ZLColorOption SelectionBackgroundOption; public final ZLColorOption SelectionBackgroundOption;
public final ZLColorOption HighlightedTextOption; public final ZLColorOption HighlightingOption;
public final ZLColorOption RegularTextOption; public final ZLColorOption RegularTextOption;
public final ZLColorOption HyperlinkTextOption; public final ZLColorOption HyperlinkTextOption;
@ -60,30 +63,30 @@ public class ColorProfile {
this(name); this(name);
BackgroundOption.setValue(base.BackgroundOption.getValue()); BackgroundOption.setValue(base.BackgroundOption.getValue());
SelectionBackgroundOption.setValue(base.SelectionBackgroundOption.getValue()); SelectionBackgroundOption.setValue(base.SelectionBackgroundOption.getValue());
HighlightedTextOption.setValue(base.HighlightedTextOption.getValue()); HighlightingOption.setValue(base.HighlightingOption.getValue());
RegularTextOption.setValue(base.RegularTextOption.getValue()); RegularTextOption.setValue(base.RegularTextOption.getValue());
HyperlinkTextOption.setValue(base.HyperlinkTextOption.getValue()); HyperlinkTextOption.setValue(base.HyperlinkTextOption.getValue());
} }
private ColorProfile(String name) { private ColorProfile(String name) {
if ("defaultDark".equals(name)) { if (NIGHT.equals(name)) {
BackgroundOption = BackgroundOption =
new ZLColorOption("Colors", name + ":Background", new ZLColor(0, 0, 0)); new ZLColorOption("Colors", name + ":Background", new ZLColor(0, 0, 0));
SelectionBackgroundOption = SelectionBackgroundOption =
new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194)); new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194));
HighlightedTextOption = HighlightingOption =
new ZLColorOption("Colors", name + ":SelectedText", new ZLColor(45, 105, 192)); new ZLColorOption("Colors", name + ":Highlighting", new ZLColor(96, 96, 128));
RegularTextOption = RegularTextOption =
new ZLColorOption("Colors", name + ":Text", new ZLColor(192, 192, 192)); new ZLColorOption("Colors", name + ":Text", new ZLColor(192, 192, 192));
HyperlinkTextOption = HyperlinkTextOption =
new ZLColorOption("Colors", name + ":Hyperlink", new ZLColor(45, 105, 192)); new ZLColorOption("Colors", name + ":Hyperlink", new ZLColor(60, 142, 224));
} else { } else {
BackgroundOption = BackgroundOption =
new ZLColorOption("Colors", name + ":Background", new ZLColor(255, 255, 255)); new ZLColorOption("Colors", name + ":Background", new ZLColor(255, 255, 255));
SelectionBackgroundOption = SelectionBackgroundOption =
new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194)); new ZLColorOption("Colors", name + ":SelectionBackground", new ZLColor(82, 131, 194));
HighlightedTextOption = HighlightingOption =
new ZLColorOption("Colors", name + ":SelectedText", new ZLColor(60, 139, 255)); new ZLColorOption("Colors", name + ":Highlighting", new ZLColor(255, 192, 128));
RegularTextOption = RegularTextOption =
new ZLColorOption("Colors", name + ":Text", new ZLColor(0, 0, 0)); new ZLColorOption("Colors", name + ":Text", new ZLColor(0, 0, 0));
HyperlinkTextOption = HyperlinkTextOption =

View file

@ -41,12 +41,6 @@ import org.geometerplus.fbreader.library.Book;
import org.geometerplus.fbreader.library.Bookmark; import org.geometerplus.fbreader.library.Bookmark;
public final class FBReader extends ZLApplication { 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 = public final ZLStringOption BookSearchPatternOption =
new ZLStringOption("BookSearch", "Pattern", ""); new ZLStringOption("BookSearch", "Pattern", "");
public final ZLStringOption TextSearchPatternOption = public final ZLStringOption TextSearchPatternOption =
@ -70,16 +64,13 @@ public final class FBReader extends ZLApplication {
new ZLBooleanOption("Options", "IsSelectionEnabled", true); new ZLBooleanOption("Options", "IsSelectionEnabled", true);
final ZLStringOption ColorProfileOption = final ZLStringOption ColorProfileOption =
new ZLStringOption("Options", "ColorProfile", "defaultLight"); new ZLStringOption("Options", "ColorProfile", ColorProfile.DAY);
private final ZLKeyBindings myBindings0 = new ZLKeyBindings("Keys"); private final ZLKeyBindings myBindings0 = new ZLKeyBindings("Keys");
private final ZLKeyBindings myBindings90 = new ZLKeyBindings("Keys90"); private final ZLKeyBindings myBindings90 = new ZLKeyBindings("Keys90");
private final ZLKeyBindings myBindings180 = new ZLKeyBindings("Keys180"); private final ZLKeyBindings myBindings180 = new ZLKeyBindings("Keys180");
private final ZLKeyBindings myBindings270 = new ZLKeyBindings("Keys270"); private final ZLKeyBindings myBindings270 = new ZLKeyBindings("Keys270");
private int myMode = ViewMode.UNDEFINED;
private int myPreviousMode = ViewMode.BOOK_TEXT;
public final FBView BookTextView; public final FBView BookTextView;
final FBView FootnoteView; final FBView FootnoteView;
@ -122,10 +113,13 @@ public final class FBReader extends ZLApplication {
//addAction(ActionCode.CLEAR_SELECTION, new DummyAction(this)); //addAction(ActionCode.CLEAR_SELECTION, new DummyAction(this));
addAction(ActionCode.FOLLOW_HYPERLINK, new FollowHyperlinkAction(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); BookTextView = new FBView(this);
FootnoteView = new FBView(this); FootnoteView = new FBView(this);
setMode(ViewMode.BOOK_TEXT); setView(BookTextView);
} }
public void initWindow() { public void initWindow() {
@ -156,7 +150,7 @@ public final class FBReader extends ZLApplication {
public ColorProfile getColorProfile() { public ColorProfile getColorProfile() {
if (myColorProfile == null) { if (myColorProfile == null) {
myColorProfile = ColorProfile.get(ColorProfileOption.getValue()); myColorProfile = ColorProfile.get(getColorProfileName());
} }
return myColorProfile; return myColorProfile;
} }
@ -193,35 +187,6 @@ public final class FBReader extends ZLApplication {
return (FBView)getCurrentView(); 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) { void tryOpenFootnote(String id) {
if (Model != null) { if (Model != null) {
BookModel.Label label = Model.getLabel(id); BookModel.Label label = Model.getLabel(id);
@ -230,7 +195,7 @@ public final class FBReader extends ZLApplication {
BookTextView.gotoPosition(label.ParagraphIndex, 0, 0); BookTextView.gotoPosition(label.ParagraphIndex, 0, 0);
} else { } else {
FootnoteView.setModel(label.Model); FootnoteView.setModel(label.Model);
setMode(ViewMode.FOOTNOTE); setView(FootnoteView);
FootnoteView.gotoPosition(label.ParagraphIndex, 0, 0); FootnoteView.gotoPosition(label.ParagraphIndex, 0, 0);
} }
repaintView(); repaintView();
@ -264,7 +229,7 @@ public final class FBReader extends ZLApplication {
BookTextView.setModel(Model.BookTextModel); BookTextView.setModel(Model.BookTextModel);
BookTextView.gotoPosition(book.getStoredPosition()); BookTextView.gotoPosition(book.getStoredPosition());
if (bookmark == null) { if (bookmark == null) {
setMode(ViewMode.BOOK_TEXT); setView(BookTextView);
} else { } else {
gotoBookmark(bookmark); gotoBookmark(bookmark);
} }
@ -278,17 +243,17 @@ public final class FBReader extends ZLApplication {
final String modelId = bookmark.getModelId(); final String modelId = bookmark.getModelId();
if (modelId == null) { if (modelId == null) {
BookTextView.gotoPosition(bookmark); BookTextView.gotoPosition(bookmark);
setMode(ViewMode.BOOK_TEXT); setView(BookTextView);
} else { } else {
FootnoteView.setModel(Model.getFootnoteModel(modelId)); FootnoteView.setModel(Model.getFootnoteModel(modelId));
FootnoteView.gotoPosition(bookmark); FootnoteView.gotoPosition(bookmark);
setMode(ViewMode.FOOTNOTE); setView(FootnoteView);
} }
repaintView(); repaintView();
} }
public void showBookTextView() { public void showBookTextView() {
setMode(ViewMode.BOOK_TEXT); setView(BookTextView);
} }
private Book createBookForFile(ZLFile file) { private Book createBookForFile(ZLFile file) {

View file

@ -215,30 +215,37 @@ public final class FBView extends ZLTextView {
return true; return true;
} }
@Override
public int getLeftMargin() { public int getLeftMargin() {
return myReader.LeftMarginOption.getValue(); return myReader.LeftMarginOption.getValue();
} }
@Override
public int getRightMargin() { public int getRightMargin() {
return myReader.RightMarginOption.getValue(); return myReader.RightMarginOption.getValue();
} }
@Override
public int getTopMargin() { public int getTopMargin() {
return myReader.TopMarginOption.getValue(); return myReader.TopMarginOption.getValue();
} }
@Override
public int getBottomMargin() { public int getBottomMargin() {
return myReader.BottomMarginOption.getValue(); return myReader.BottomMarginOption.getValue();
} }
@Override
public ZLColor getBackgroundColor() { public ZLColor getBackgroundColor() {
return myReader.getColorProfile().BackgroundOption.getValue(); return myReader.getColorProfile().BackgroundOption.getValue();
} }
@Override
public ZLColor getSelectedBackgroundColor() { public ZLColor getSelectedBackgroundColor() {
return myReader.getColorProfile().SelectionBackgroundOption.getValue(); return myReader.getColorProfile().SelectionBackgroundOption.getValue();
} }
@Override
public ZLColor getTextColor(byte hyperlinkType) { public ZLColor getTextColor(byte hyperlinkType) {
final ColorProfile profile = myReader.getColorProfile(); final ColorProfile profile = myReader.getColorProfile();
switch (hyperlinkType) { switch (hyperlinkType) {
@ -251,8 +258,9 @@ public final class FBView extends ZLTextView {
} }
} }
public ZLColor getHighlightedTextColor() { @Override
return myReader.getColorProfile().HighlightedTextOption.getValue(); public ZLColor getHighlightingColor() {
return myReader.getColorProfile().HighlightingOption.getValue();
} }
protected boolean isSelectionEnabled() { protected boolean isSelectionEnabled() {

View file

@ -25,7 +25,7 @@ class ScrollToHomeAction extends FBAction {
} }
public boolean isVisible() { public boolean isVisible() {
return Reader.getMode() == FBReader.ViewMode.BOOK_TEXT; return Reader.getCurrentView() == Reader.BookTextView;
} }
public boolean isEnabled() { public boolean isEnabled() {

View file

@ -19,21 +19,22 @@
package org.geometerplus.fbreader.fbreader; package org.geometerplus.fbreader.fbreader;
class SetModeAction extends FBAction { import org.geometerplus.zlibrary.core.dialogs.ZLDialogManager;
SetModeAction(FBReader fbreader, int modeToSet, int visibleInModes) {
class SwitchProfileAction extends FBAction {
private String myProfileName;
SwitchProfileAction(FBReader fbreader, String profileName) {
super(fbreader); super(fbreader);
myModeToSet = modeToSet; myProfileName = profileName;
myVisibleInModes = visibleInModes;
} }
public boolean isVisible() { public boolean isVisible() {
return (Reader.getMode() & myVisibleInModes) != 0; return !myProfileName.equals(Reader.getColorProfileName());
} }
public void run() { 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 String myConvertedTextBuffer;
private boolean myParagraphStarted = false; private boolean myParagraphStarted = false;
private boolean myBufferIsEmpty; private boolean myBufferIsEmpty;
private ZLTextForcedControlEntry myForcedEntry; //private ZLTextForcedControlEntry myForcedEntry;
private final ArrayList/*<std::pair<FBTextKind,bool> >*/ myDelayedControls = new ArrayList(); private final ArrayList/*<std::pair<FBTextKind,bool> >*/ myDelayedControls = new ArrayList();
private final ArrayList/*<std::string> */myDelayedHyperlinks = new ArrayList(); private final ArrayList/*<std::string> */myDelayedHyperlinks = new ArrayList();
private short myCompressionVersion; private short myCompressionVersion;
@ -59,7 +59,7 @@ public class PluckerBookReader extends BookReader {
//System.out.println(filePath + " " + encoding); //System.out.println(filePath + " " + encoding);
myFont = FontType.FT_REGULAR; myFont = FontType.FT_REGULAR;
myCharBuffer = new char[65535]; myCharBuffer = new char[65535];
myForcedEntry = null; //myForcedEntry = null;
} }
public boolean readDocument() { public boolean readDocument() {
@ -319,9 +319,9 @@ public class PluckerBookReader extends BookReader {
myBufferIsEmpty = false; myBufferIsEmpty = false;
} }
safeEndParagraph(); safeEndParagraph();
if (myForcedEntry != null) { //if (myForcedEntry != null) {
myForcedEntry = null; // myForcedEntry = null;
} //}
myDelayedControls.clear(); myDelayedControls.clear();
} }
@ -351,24 +351,24 @@ public class PluckerBookReader extends BookReader {
break; break;
case 0x22: case 0x22:
if (!myParagraphStarted) { if (!myParagraphStarted) {
if (myForcedEntry == null) { //if (myForcedEntry == null) {
myForcedEntry = new ZLTextForcedControlEntry(); // myForcedEntry = new ZLTextForcedControlEntry();
} //}
myForcedEntry.setLeftIndent((short)ptr[cur + 1]); //myForcedEntry.setLeftIndent((short)ptr[cur + 1]);
myForcedEntry.setRightIndent((short)ptr[cur + 2]); //myForcedEntry.setRightIndent((short)ptr[cur + 2]);
} }
break; break;
case 0x29: case 0x29:
if (!myParagraphStarted) { if (!myParagraphStarted) {
if (myForcedEntry == null) { //if (myForcedEntry == null) {
myForcedEntry = new ZLTextForcedControlEntry(); // myForcedEntry = new ZLTextForcedControlEntry();
} //}
switch (ptr[cur + 1]) { //switch (ptr[cur + 1]) {
case 0: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_LEFT); break; // case 0: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_LEFT); break;
case 1: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_RIGHT); break; // case 1: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_RIGHT); break;
case 2: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_CENTER); break; // case 2: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_CENTER); break;
case 3: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_JUSTIFY); break; // case 3: myForcedEntry.setAlignmentType(ZLTextAlignmentType.ALIGN_JUSTIFY); break;
} //}
} }
break; break;
case 0x33: // just break line instead of horizontal rule (TODO: draw horizontal rule?) 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(); Pair pit = (Pair)it.next();
addControl((Byte)pit.myFirst, (Boolean)pit.mySecond); addControl((Byte)pit.myFirst, (Boolean)pit.mySecond);
} }
if (myForcedEntry != null) { //if (myForcedEntry != null) {
addControl(myForcedEntry); // addControl(myForcedEntry);
} else { //} else {
addControl(FBTextKind.REGULAR, true); addControl(FBTextKind.REGULAR, true);
} //}
for (Iterator it = myDelayedHyperlinks.iterator(); it.hasNext(); ) { for (Iterator it = myDelayedHyperlinks.iterator(); it.hasNext(); ) {
addHyperlinkControl(FBTextKind.INTERNAL_HYPERLINK, (String)it.next()); addHyperlinkControl(FBTextKind.INTERNAL_HYPERLINK, (String)it.next());
} }

View file

@ -62,9 +62,9 @@ public class OptionsDialog {
final String BACKGROUND = resource.getResource("background").getValue(); final String BACKGROUND = resource.getResource("background").getValue();
final ColorProfile profile = fbreader.getColorProfile(); final ColorProfile profile = fbreader.getColorProfile();
builder.addOption(BACKGROUND, profile.BackgroundOption); 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("text").getValue(), profile.RegularTextOption);
builder.addOption(resource.getResource("hyperlink").getValue(), profile.HyperlinkTextOption); builder.addOption(resource.getResource("hyperlink").getValue(), profile.HyperlinkTextOption);
builder.addOption(resource.getResource("highlighted").getValue(), profile.HighlightedTextOption);
builder.setInitial(BACKGROUND); builder.setInitial(BACKGROUND);
colorsTab.addOption(colorKey, builder.comboEntry()); colorsTab.addOption(colorKey, builder.comboEntry());
colorsTab.addOption("", builder.colorEntry()); colorsTab.addOption("", builder.colorEntry());

View file

@ -19,12 +19,12 @@
package org.geometerplus.zlibrary.text.model; package org.geometerplus.zlibrary.text.model;
public class ZLTextForcedControlEntry { public final class ZLTextForcedControlEntry {
private final static int SUPPORTS_LEFT_INDENT = 1 << 0; final static short SUPPORTS_LEFT_INDENT = 1 << 0;
private final static int SUPPORTS_RIGHT_INDENT = 1 << 1; final static short SUPPORTS_RIGHT_INDENT = 1 << 1;
private final static int SUPPORTS_ALIGNMENT_TYPE = 1 << 2; final static short SUPPORTS_ALIGNMENT_TYPE = 1 << 2;
private int myMask; private short myMask;
private short myLeftIndent; private short myLeftIndent;
private short myRightIndent; private short myRightIndent;
private byte myAlignmentType; private byte myAlignmentType;
@ -32,6 +32,10 @@ public class ZLTextForcedControlEntry {
public ZLTextForcedControlEntry() { public ZLTextForcedControlEntry() {
} }
short getMask() {
return myMask;
};
public boolean isLeftIndentSupported() { public boolean isLeftIndentSupported() {
return (myMask & SUPPORTS_LEFT_INDENT) == SUPPORTS_LEFT_INDENT; 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; import org.geometerplus.zlibrary.core.image.ZLImageMap;
public final class ZLTextPlainModel implements ZLTextWritableModel { public class ZLTextPlainModel implements ZLTextModel {
private final String myId; protected final String myId;
private int[] myStartEntryIndices; protected int[] myStartEntryIndices;
private int[] myStartEntryOffsets; protected int[] myStartEntryOffsets;
private int[] myParagraphLengths; protected int[] myParagraphLengths;
private byte[] myParagraphKinds; 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; protected final ZLImageMap myImageMap;
private final ArrayList<ZLTextMark> myMarks = new ArrayList<ZLTextMark>();
private char[] myCurrentDataBlock;
private int myBlockOffset;
final class EntryIteratorImpl implements ZLTextParagraph.EntryIterator { final class EntryIteratorImpl implements ZLTextParagraph.EntryIterator {
private int myCounter; private int myCounter;
@ -59,6 +59,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
private String myHyperlinkId; private String myHyperlinkId;
private ZLImageEntry myImageEntry; private ZLImageEntry myImageEntry;
private ZLTextForcedControlEntry myForcedControlEntry;
private short myFixedHSpaceLength; private short myFixedHSpaceLength;
@ -106,6 +107,10 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
return myImageEntry; return myImageEntry;
} }
public ZLTextForcedControlEntry getForcedControlEntry() {
return myForcedControlEntry;
}
public short getFixedHSpaceLength() { public short getFixedHSpaceLength() {
return myFixedHSpaceLength; return myFixedHSpaceLength;
} }
@ -153,10 +158,11 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
} }
case ZLTextParagraph.Entry.IMAGE: case ZLTextParagraph.Entry.IMAGE:
{ {
final int entryAddress = final short vOffset = (short)data[dataOffset++];
((int)data[dataOffset++] << 16) + final short len = (short)data[dataOffset++];
(int)data[dataOffset++]; final String id = new String(data, dataOffset, len);
myImageEntry = (ZLImageEntry)myEntries.get(entryAddress); dataOffset += len;
myImageEntry = new ZLImageEntry(myImageMap, id, vOffset);
break; break;
} }
case ZLTextParagraph.Entry.FIXED_HSPACE: case ZLTextParagraph.Entry.FIXED_HSPACE:
@ -164,11 +170,21 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
break; break;
case ZLTextParagraph.Entry.FORCED_CONTROL: case ZLTextParagraph.Entry.FORCED_CONTROL:
{ {
final int entryAddress = final int mask = (int)data[dataOffset++];
((int)data[dataOffset++] << 16) + final ZLTextForcedControlEntry entry = new ZLTextForcedControlEntry();
(int)data[dataOffset++]; if ((mask & ZLTextForcedControlEntry.SUPPORTS_LEFT_INDENT) ==
//entry = myEntries.get((int)code); ZLTextForcedControlEntry.SUPPORTS_LEFT_INDENT) {
break; 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; ++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; myId = id;
myStartEntryIndices = new int[arraySize]; myStartEntryIndices = new int[arraySize];
myStartEntryOffsets = new int[arraySize]; myStartEntryOffsets = new int[arraySize];
myParagraphLengths = new int[arraySize]; myParagraphLengths = new int[arraySize];
myParagraphKinds = new byte[arraySize]; myParagraphKinds = new byte[arraySize];
myStorage = new CachedCharStorage(dataBlockSize, directoryName, extension); myStorage = new CachedCharStorage(dataBlockSize, directoryName, extension);
myImageMap = imageMap;
} }
public String getId() { public final String getId() {
return myId; return myId;
} }
private void extend() { public final ZLTextMark getFirstMark() {
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() {
return myMarks.isEmpty() ? null : myMarks.get(0); return myMarks.isEmpty() ? null : myMarks.get(0);
} }
public ZLTextMark getLastMark() { public final ZLTextMark getLastMark() {
return myMarks.isEmpty() ? null : myMarks.get(myMarks.size() - 1); return myMarks.isEmpty() ? null : myMarks.get(myMarks.size() - 1);
} }
public ZLTextMark getNextMark(ZLTextMark position) { public final ZLTextMark getNextMark(ZLTextMark position) {
if (position == null) { if (position == null) {
return null; return null;
} }
@ -317,7 +230,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
return mark; return mark;
} }
public ZLTextMark getPreviousMark(ZLTextMark position) { public final ZLTextMark getPreviousMark(ZLTextMark position) {
if (position == null) { if (position == null) {
return null; return null;
} }
@ -333,7 +246,7 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
return mark; 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; int count = 0;
ZLSearchPattern pattern = new ZLSearchPattern(text, ignoreCase); ZLSearchPattern pattern = new ZLSearchPattern(text, ignoreCase);
myMarks.clear(); myMarks.clear();
@ -364,26 +277,26 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
return count; return count;
} }
public ArrayList getMarks() { public final ArrayList<ZLTextMark> getMarks() {
return myMarks; return myMarks;
} }
public void removeAllMarks() { public final void removeAllMarks() {
myMarks.clear(); myMarks.clear();
} }
public int getParagraphsNumber() { public final int getParagraphsNumber() {
return myParagraphsNumber; return myParagraphsNumber;
} }
public ZLTextParagraph getParagraph(int index) { public final ZLTextParagraph getParagraph(int index) {
final byte kind = myParagraphKinds[index]; final byte kind = myParagraphKinds[index];
return (kind == ZLTextParagraph.Kind.TEXT_PARAGRAPH) ? return (kind == ZLTextParagraph.Kind.TEXT_PARAGRAPH) ?
new ZLTextParagraphImpl(this, index) : new ZLTextParagraphImpl(this, index) :
new ZLTextSpecialParagraphImpl(kind, this, index); new ZLTextSpecialParagraphImpl(kind, this, index);
} }
public int getParagraphTextLength(int index) { public final int getParagraphTextLength(int index) {
int textLength = 0; int textLength = 0;
int dataIndex = myStartEntryIndices[index]; int dataIndex = myStartEntryIndices[index];
int dataOffset = myStartEntryOffsets[index]; int dataOffset = myStartEntryOffsets[index];
@ -417,13 +330,16 @@ public final class ZLTextPlainModel implements ZLTextWritableModel {
break; break;
} }
case ZLTextParagraph.Entry.IMAGE: case ZLTextParagraph.Entry.IMAGE:
dataOffset += 2; dataOffset++;
dataOffset += (short)data[dataOffset++];
break; break;
case ZLTextParagraph.Entry.FIXED_HSPACE: case ZLTextParagraph.Entry.FIXED_HSPACE:
++dataOffset; ++dataOffset;
break; break;
case ZLTextParagraph.Entry.FORCED_CONTROL: case ZLTextParagraph.Entry.FORCED_CONTROL:
dataOffset += 2; for (int mask = (int)data[dataOffset++]; mask != 0; mask >>= 1) {
dataOffset += mask & 1;
}
break; break;
} }
} }

View file

@ -28,8 +28,8 @@ public interface ZLTextWritableModel extends ZLTextModel {
void addText(char[] text); void addText(char[] text);
void addText(char[] text, int offset, int length); 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 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); 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); context.drawImage(areaX, areaY, ((ZLTextImageElement)element).ImageData);
} else if (element == ZLTextElement.HSpace) { } else if (element == ZLTextElement.HSpace) {
final int cw = context.getSpaceWidth(); 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) { for (int len = 0; len < area.XEnd - area.XStart; len += cw) {
context.drawString(areaX + len, areaY, SPACE, 0, 1); 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 getBackgroundColor();
public abstract ZLColor getSelectedBackgroundColor(); public abstract ZLColor getSelectedBackgroundColor();
public abstract ZLColor getTextColor(byte hyperlinkType); public abstract ZLColor getTextColor(byte hyperlinkType);
public abstract ZLColor getHighlightedTextColor(); public abstract ZLColor getHighlightingColor();
int getTextAreaHeight() { int getTextAreaHeight() {
return Context.getHeight() - getTopMargin() - getBottomMargin(); return Context.getHeight() - getTopMargin() - getBottomMargin();
@ -230,10 +230,12 @@ abstract class ZLTextViewBase extends ZLView {
} }
if (markStart < length) { if (markStart < length) {
context.setTextColor(getHighlightedTextColor()); context.setFillColor(getHighlightingColor());
int endPos = Math.min(markStart + markLen, length); 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); 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)); context.setTextColor(getTextColor(myTextStyle.Hyperlink.Type));
} }
pos = markStart + markLen; pos = markStart + markLen;