diff --git a/jni/NativeFormats/JavaNativeFormatPlugin.cpp b/jni/NativeFormats/JavaNativeFormatPlugin.cpp index fb0dfad24..4df4eb7d9 100644 --- a/jni/NativeFormats/JavaNativeFormatPlugin.cpp +++ b/jni/NativeFormats/JavaNativeFormatPlugin.cpp @@ -255,8 +255,21 @@ static void initTOC(JNIEnv *env, jobject javaModel, const ContentsTree &tree) { } } -static jstring createJavaString(JNIEnv *env, shared_ptr info) { - return info.isNull() ? 0 : AndroidUtil::createJavaString(env, info->Path); +static jobject createJavaFileInfo(JNIEnv *env, shared_ptr info) { + if (info.isNull()) { + return 0; + } + + JString path(env, info->Path, false); + jobject encryptionInfo = AndroidUtil::createJavaEncryptionInfo(env, info->EncryptionInfo); + + jobject fileInfo = AndroidUtil::Constructor_FileInfo->call(path.j(), encryptionInfo); + + if (encryptionInfo != 0) { + env->DeleteLocalRef(encryptionInfo); + } + + return fileInfo; } extern "C" @@ -327,10 +340,10 @@ JNIEXPORT jint JNICALL Java_org_geometerplus_fbreader_formats_NativeFormatPlugin continue; } JString family(env, it->first); - jstring normal = createJavaString(env, it->second->Normal); - jstring bold = createJavaString(env, it->second->Bold); - jstring italic = createJavaString(env, it->second->Italic); - jstring boldItalic = createJavaString(env, it->second->BoldItalic); + jobject normal = createJavaFileInfo(env, it->second->Normal); + jobject bold = createJavaFileInfo(env, it->second->Bold); + jobject italic = createJavaFileInfo(env, it->second->Italic); + jobject boldItalic = createJavaFileInfo(env, it->second->BoldItalic); AndroidUtil::Method_NativeBookModel_registerFontEntry->call( javaModel, family.j(), normal, bold, italic, boldItalic diff --git a/jni/NativeFormats/util/AndroidUtil.cpp b/jni/NativeFormats/util/AndroidUtil.cpp index 8859578d1..9b067e298 100644 --- a/jni/NativeFormats/util/AndroidUtil.cpp +++ b/jni/NativeFormats/util/AndroidUtil.cpp @@ -37,6 +37,7 @@ JavaClass AndroidUtil::Class_java_io_InputStream("java/io/InputStream"); JavaClass AndroidUtil::Class_ZLibrary("org/geometerplus/zlibrary/core/library/ZLibrary"); JavaClass AndroidUtil::Class_ZLFile("org/geometerplus/zlibrary/core/filesystem/ZLFile"); +JavaClass AndroidUtil::Class_FileInfo("org/geometerplus/zlibrary/core/fonts/FileInfo"); JavaClass AndroidUtil::Class_FileEncryptionInfo("org/geometerplus/zlibrary/core/drm/FileEncryptionInfo"); JavaClass AndroidUtil::Class_ZLFileImage("org/geometerplus/zlibrary/core/image/ZLFileImage"); JavaClass AndroidUtil::Class_ZLTextModel("org/geometerplus/zlibrary/text/model/ZLTextModel"); @@ -95,6 +96,7 @@ shared_ptr AndroidUtil::Method_ZLFile_getPath; shared_ptr AndroidUtil::Method_ZLFile_isDirectory; shared_ptr AndroidUtil::Method_ZLFile_size; +shared_ptr AndroidUtil::Constructor_FileInfo; shared_ptr AndroidUtil::Constructor_FileEncryptionInfo; shared_ptr AndroidUtil::Constructor_ZLFileImage; @@ -178,6 +180,7 @@ bool AndroidUtil::init(JavaVM* jvm) { Method_ZLFile_getPath = new StringMethod(Class_ZLFile, "getPath", "()"); Method_ZLFile_size = new LongMethod(Class_ZLFile, "size", "()"); + Constructor_FileInfo = new Constructor(Class_FileInfo, "(Ljava/lang/String;Lorg/geometerplus/zlibrary/core/drm/FileEncryptionInfo;)V"); Constructor_FileEncryptionInfo = new Constructor(Class_FileEncryptionInfo, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); Constructor_ZLFileImage = new Constructor(Class_ZLFileImage, "(Ljava/lang/String;Lorg/geometerplus/zlibrary/core/filesystem/ZLFile;Ljava/lang/String;[I[ILorg/geometerplus/zlibrary/core/drm/FileEncryptionInfo;)V"); @@ -207,7 +210,7 @@ bool AndroidUtil::init(JavaVM* jvm) { Method_NativeBookModel_setFootnoteModel = new VoidMethod(Class_NativeBookModel, "setFootnoteModel", "(Lorg/geometerplus/zlibrary/text/model/ZLTextModel;)"); Method_NativeBookModel_addImage = new VoidMethod(Class_NativeBookModel, "addImage", "(Ljava/lang/String;Lorg/geometerplus/zlibrary/core/image/ZLImage;)"); Method_NativeBookModel_registerFontFamilyList = new VoidMethod(Class_NativeBookModel, "registerFontFamilyList", "([Ljava/lang/String;)"); - Method_NativeBookModel_registerFontEntry = new VoidMethod(Class_NativeBookModel, "registerFontEntry", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)"); + Method_NativeBookModel_registerFontEntry = new VoidMethod(Class_NativeBookModel, "registerFontEntry", "(Ljava/lang/String;Lorg/geometerplus/zlibrary/core/fonts/FileInfo;Lorg/geometerplus/zlibrary/core/fonts/FileInfo;Lorg/geometerplus/zlibrary/core/fonts/FileInfo;Lorg/geometerplus/zlibrary/core/fonts/FileInfo;)"); /* Class_BookReadingException = new JavaClass(env, "org/geometerplus/fbreader/bookmodel/BookReadingException"); diff --git a/jni/NativeFormats/util/AndroidUtil.h b/jni/NativeFormats/util/AndroidUtil.h index a056a1967..8fe8eb8ff 100644 --- a/jni/NativeFormats/util/AndroidUtil.h +++ b/jni/NativeFormats/util/AndroidUtil.h @@ -76,6 +76,7 @@ public: static JavaClass Class_java_io_InputStream; static JavaClass Class_ZLibrary; static JavaClass Class_ZLFile; + static JavaClass Class_FileInfo; static JavaClass Class_FileEncryptionInfo; static JavaClass Class_ZLFileImage; static JavaClass Class_ZLTextModel; @@ -117,6 +118,7 @@ public: static shared_ptr Method_ZLFile_isDirectory; static shared_ptr Method_ZLFile_size; + static shared_ptr Constructor_FileInfo; static shared_ptr Constructor_FileEncryptionInfo; static shared_ptr Constructor_ZLFileImage; diff --git a/src/org/geometerplus/fbreader/bookmodel/BookModel.java b/src/org/geometerplus/fbreader/bookmodel/BookModel.java index 0bda7be07..e2ce005d9 100644 --- a/src/org/geometerplus/fbreader/bookmodel/BookModel.java +++ b/src/org/geometerplus/fbreader/bookmodel/BookModel.java @@ -22,8 +22,7 @@ package org.geometerplus.fbreader.bookmodel; import java.util.Arrays; import java.util.List; -import org.geometerplus.zlibrary.core.fonts.FontEntry; -import org.geometerplus.zlibrary.core.fonts.FontManager; +import org.geometerplus.zlibrary.core.fonts.*; import org.geometerplus.zlibrary.text.model.*; import org.geometerplus.fbreader.book.Book; @@ -106,7 +105,7 @@ public abstract class BookModel { FontManager.Entries.put(family, entry); } - public void registerFontEntry(String family, String normal, String bold, String italic, String boldItalic) { + public void registerFontEntry(String family, FileInfo normal, FileInfo bold, FileInfo italic, FileInfo boldItalic) { registerFontEntry(family, new FontEntry(family, normal, bold, italic, boldItalic)); } } diff --git a/src/org/geometerplus/zlibrary/core/drm/FileEncryptionInfo.java b/src/org/geometerplus/zlibrary/core/drm/FileEncryptionInfo.java index 0fca27576..90304ca74 100644 --- a/src/org/geometerplus/zlibrary/core/drm/FileEncryptionInfo.java +++ b/src/org/geometerplus/zlibrary/core/drm/FileEncryptionInfo.java @@ -19,6 +19,8 @@ package org.geometerplus.zlibrary.core.drm; +import org.geometerplus.zlibrary.core.util.MiscUtil; + public class FileEncryptionInfo { public final String Uri; public final String Method; @@ -31,4 +33,29 @@ public class FileEncryptionInfo { Algorithm = algorithm; ContentId = contentId; } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof FileEncryptionInfo)) { + return false; + } + final FileEncryptionInfo oInfo = (FileEncryptionInfo)other; + return + MiscUtil.equals(Uri, oInfo.Uri) && + MiscUtil.equals(Method, oInfo.Method) && + MiscUtil.equals(Algorithm, oInfo.Algorithm) && + MiscUtil.equals(ContentId, oInfo.ContentId); + } + + @Override + public int hashCode() { + return + MiscUtil.hashCode(Uri) + + 23 * (MiscUtil.hashCode(Method) + + 23 * (MiscUtil.hashCode(Algorithm) + + 23 * MiscUtil.hashCode(ContentId))); + } } diff --git a/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java b/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java index 2f4effee3..61d9161ed 100644 --- a/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java +++ b/src/org/geometerplus/zlibrary/core/filesystem/ZLFile.java @@ -22,6 +22,8 @@ package org.geometerplus.zlibrary.core.filesystem; import java.io.*; import java.util.*; +import org.geometerplus.zlibrary.core.drm.FileEncryptionInfo; + public abstract class ZLFile { private final static HashMap ourCachedFiles = new HashMap(); @@ -142,6 +144,14 @@ public abstract class ZLFile { public abstract ZLPhysicalFile getPhysicalFile(); public abstract InputStream getInputStream() throws IOException; + public final InputStream getInputStream(FileEncryptionInfo encryptionInfo) throws IOException { + if (encryptionInfo == null) { + return getInputStream(); + } + + throw new IOException("Encryption method " + encryptionInfo.Method + " is not supported"); + } + public String getUrl() { return "file://" + getPath(); } diff --git a/src/org/geometerplus/zlibrary/core/fonts/FontEntry.java b/src/org/geometerplus/zlibrary/core/fonts/FontEntry.java index 2e6abc56a..0e2157e13 100644 --- a/src/org/geometerplus/zlibrary/core/fonts/FontEntry.java +++ b/src/org/geometerplus/zlibrary/core/fonts/FontEntry.java @@ -39,37 +39,38 @@ public final class FontEntry { } public final String Family; - private final String[] myFiles; + private final FileInfo[] myFileInfos; - public FontEntry(String family, String normal, String bold, String italic, String boldItalic) { + public FontEntry(String family, FileInfo normal, FileInfo bold, FileInfo italic, FileInfo boldItalic) { Family = family; - myFiles = new String[4]; - myFiles[0] = normal; - myFiles[1] = bold; - myFiles[2] = italic; - myFiles[3] = boldItalic; + myFileInfos = new FileInfo[4]; + myFileInfos[0] = normal; + myFileInfos[1] = bold; + myFileInfos[2] = italic; + myFileInfos[3] = boldItalic; } FontEntry(String family) { Family = family; - myFiles = null; + myFileInfos = null; } public boolean isSystem() { - return myFiles == null; + return myFileInfos == null; } - public String fileName(boolean bold, boolean italic) { - return myFiles != null ? myFiles[(bold ? 1 : 0) + (italic ? 2 : 0)] : null; + public FileInfo fileInfo(boolean bold, boolean italic) { + return myFileInfos != null ? myFileInfos[(bold ? 1 : 0) + (italic ? 2 : 0)] : null; } @Override public String toString() { final StringBuilder builder = new StringBuilder("FontEntry["); builder.append(Family); - if (myFiles != null) { + if (myFileInfos != null) { for (int i = 0; i < 4; ++i) { - builder.append(";").append(myFiles[i]); + final FileInfo info = myFileInfos[i]; + builder.append(";").append(info != null ? info.Path : null); } } return builder.append("]").toString(); @@ -87,14 +88,14 @@ public final class FontEntry { if (!Family.equals(entry.Family)) { return false; } - if (myFiles == null) { - return entry.myFiles == null; + if (myFileInfos == null) { + return entry.myFileInfos == null; } - if (entry.myFiles == null || entry.myFiles.length != myFiles.length) { + if (entry.myFileInfos == null) { return false; } - for (int i = 0; i < myFiles.length; ++i) { - if (!MiscUtil.equals(myFiles[i], entry.myFiles[i])) { + for (int i = 0; i < myFileInfos.length; ++i) { + if (!MiscUtil.equals(myFileInfos[i], entry.myFileInfos[i])) { return false; } } diff --git a/src/org/geometerplus/zlibrary/ui/android/view/AndroidFontUtil.java b/src/org/geometerplus/zlibrary/ui/android/view/AndroidFontUtil.java index 78b763a24..603a62f76 100644 --- a/src/org/geometerplus/zlibrary/ui/android/view/AndroidFontUtil.java +++ b/src/org/geometerplus/zlibrary/ui/android/view/AndroidFontUtil.java @@ -26,6 +26,7 @@ import android.content.res.AssetManager; import android.graphics.Typeface; import org.geometerplus.zlibrary.core.filesystem.ZLFile; +import org.geometerplus.zlibrary.core.fonts.FileInfo; import org.geometerplus.zlibrary.core.fonts.FontEntry; import org.geometerplus.zlibrary.core.util.ZLTTFInfoDetector; import org.geometerplus.zlibrary.core.xml.ZLStringMap; @@ -240,11 +241,11 @@ public final class AndroidFontUtil { return builder.append(".font").toString(); } - private static boolean copy(String from, String to) { + private static boolean copy(FileInfo from, String to) { InputStream is = null; OutputStream os = null; try { - is = ZLFile.createFileByPath(from).getInputStream(); + is = ZLFile.createFileByPath(from.Path).getInputStream(from.EncryptionInfo); os = new FileOutputStream(to); final byte[] buffer = new byte[8192]; while (true) { @@ -275,10 +276,10 @@ public final class AndroidFontUtil { final Spec spec = new Spec(entry, bold, italic); Object cached = ourCachedEmbeddedTypefaces.get(spec); if (cached == null) { - final String fileName = entry.fileName(bold, italic); - if (fileName != null) { + final FileInfo fileInfo = entry.fileInfo(bold, italic); + if (fileInfo != null) { final String realFileName = alias(entry.Family, bold, italic); - if (copy(fileName, realFileName)) { + if (copy(fileInfo, realFileName)) { try { cached = Typeface.createFromFile(realFileName); } catch (Throwable t) {