Skip to content

Commit 3168577

Browse files
committed
core update and improvements
1 parent 69fe62f commit 3168577

4 files changed

Lines changed: 89 additions & 68 deletions

File tree

app/conanfile.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[requires]
2-
odrcore/5.0.0-pre6
2+
odrcore/5.0.0-pre9
33

44
[generators]
55
CMakeToolchain

app/src/main/cpp/CoreWrapper.cpp

Lines changed: 82 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <odr/html.hpp>
66
#include <odr/odr.hpp>
77
#include <odr/exceptions.hpp>
8+
#include <odr/html_service.hpp>
89
#include <odr/http_server.hpp>
910
#include <odr/global_params.hpp>
1011

@@ -18,7 +19,7 @@ namespace {
1819

1920
std::string convertString(JNIEnv *env, jstring string) {
2021
jboolean isCopy;
21-
const char* cstring = env->GetStringUTFChars(string, &isCopy);
22+
const char *cstring = env->GetStringUTFChars(string, &isCopy);
2223
auto cppstring = std::string(cstring, env->GetStringUTFLength(string));
2324
env->ReleaseStringUTFChars(string, cstring);
2425
return cppstring;
@@ -37,7 +38,7 @@ std::string getStringField(JNIEnv *env, jobject object, const char *name) {
3738

3839
}
3940

40-
std::optional<odr::Html> s_html;
41+
std::optional<odr::Document> s_document;
4142

4243
JNIEXPORT void JNICALL
4344
Java_at_tomtasche_reader_background_CoreWrapper_setGlobalParams(JNIEnv *env, jclass clazz,
@@ -126,26 +127,6 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
126127
__android_log_print(ANDROID_LOG_VERBOSE, "smn", "Open %s", inputPathCpp.c_str());
127128

128129
const auto file = odr::open(inputPathCpp);
129-
const auto fileCategory = odr::category_by_type(file.file_type());
130-
131-
if (!ooxml &&
132-
(file.file_type() == odr::FileType::office_open_xml_document ||
133-
file.file_type() == odr::FileType::office_open_xml_workbook ||
134-
file.file_type() == odr::FileType::office_open_xml_presentation ||
135-
file.file_type() == odr::FileType::office_open_xml_encrypted)) {
136-
env->SetIntField(result, errorField, -5);
137-
return result;
138-
}
139-
140-
if (!txt && fileCategory == odr::FileCategory::text) {
141-
env->SetIntField(result, errorField, -5);
142-
return result;
143-
}
144-
145-
if (!pdf && file.file_type() == odr::FileType::portable_document_format) {
146-
env->SetIntField(result, errorField, -5);
147-
return result;
148-
}
149130

150131
if (file.is_document_file()) {
151132
odr::DocumentFile document_file = file.document_file();
@@ -155,6 +136,8 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
155136
return result;
156137
}
157138
}
139+
// TODO this will cause a second load
140+
s_document = document_file.document();
158141
}
159142

160143
extensionCpp = odr::type_to_string(file.file_type());
@@ -163,16 +146,17 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
163146

164147
odr::HtmlConfig config;
165148
config.editable = editable;
166-
167-
if (paging) {
168-
config.text_document_margin = true;
169-
}
149+
config.text_document_margin = paging;
170150

171151
__android_log_print(ANDROID_LOG_VERBOSE, "smn", "Translate to HTML");
172152

173-
s_html = odr::html::translate(file, outputPathCpp, config);
153+
std::string output_tmp = outputPathCpp + "/tmp";
154+
std::filesystem::create_directories(output_tmp);
155+
odr::HtmlService service = odr::html::translate(file, output_tmp, config);
156+
odr::Html html = service.bring_offline(outputPathCpp);
157+
std::filesystem::remove_all(output_tmp);
174158

175-
for (auto &&page: s_html->pages()) {
159+
for (const odr::HtmlPage &page: html.pages()) {
176160
jstring pageName = env->NewStringUTF(page.name.c_str());
177161
env->CallBooleanMethod(pageNames, addMethod, pageName);
178162

@@ -192,7 +176,8 @@ Java_at_tomtasche_reader_background_CoreWrapper_parseNative(JNIEnv *env, jclass
192176
env->SetIntField(result, errorField, -4);
193177
return result;
194178
} catch (...) {
195-
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unhandled C++ exception without further information");
179+
__android_log_print(ANDROID_LOG_ERROR, "smn",
180+
"Unhandled C++ exception without further information");
196181
env->SetIntField(result, errorField, -4);
197182
return result;
198183
}
@@ -215,13 +200,18 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
215200

216201
jfieldID errorField = env->GetFieldID(resultClass, "errorCode", "I");
217202

203+
if (!s_document.has_value()) {
204+
env->SetIntField(result, errorField, -1);
205+
return result;
206+
}
207+
218208
try {
219209
std::string outputPathPrefixCpp = getStringField(env, options, "outputPath");
220210

221211
jboolean isCopy;
222212
const auto htmlDiffC = env->GetStringUTFChars(htmlDiff, &isCopy);
223213

224-
const auto extension = odr::type_to_string(s_html->file_type());
214+
const auto extension = odr::type_to_string(s_document->file_type());
225215
const auto outputPathCpp = outputPathPrefixCpp + "." + extension;
226216
const char *outputPathC = outputPathCpp.c_str();
227217
jstring outputPath = env->NewStringUTF(outputPathC);
@@ -230,7 +220,7 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
230220
env->SetObjectField(result, outputPathField, outputPath);
231221

232222
try {
233-
s_html->edit(htmlDiffC);
223+
odr::html::edit(*s_document, htmlDiffC);
234224

235225
env->ReleaseStringUTFChars(htmlDiff, htmlDiffC);
236226
} catch (...) {
@@ -241,7 +231,7 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
241231
}
242232

243233
try {
244-
s_html->save(outputPathCpp);
234+
s_document->save(outputPathCpp);
245235
} catch (...) {
246236
env->SetIntField(result, errorField, -7);
247237
return result;
@@ -258,26 +248,28 @@ Java_at_tomtasche_reader_background_CoreWrapper_backtranslateNative(JNIEnv *env,
258248
JNIEXPORT void JNICALL
259249
Java_at_tomtasche_reader_background_CoreWrapper_closeNative(JNIEnv *env, jclass clazz,
260250
jobject options) {
261-
s_html.reset();
251+
s_document.reset();
262252
}
263253

264254
std::optional<odr::HttpServer> s_server;
265255

266256
JNIEXPORT void JNICALL
267-
Java_at_tomtasche_reader_background_CoreWrapper_createServer(JNIEnv *env, jclass clazz, jstring outputPath) {
257+
Java_at_tomtasche_reader_background_CoreWrapper_createServer(JNIEnv *env, jclass clazz,
258+
jstring cachePath) {
268259
__android_log_print(ANDROID_LOG_INFO, "smn", "create server");
269260

270-
std::string output_path = convertString(env, outputPath);
261+
std::string cachePathCpp = convertString(env, cachePath);
271262

272-
std::filesystem::create_directories(output_path);
263+
std::filesystem::create_directories(cachePathCpp);
273264

274265
odr::HttpServer::Config config;
275-
config.output_path = output_path;
266+
config.cache_path = cachePathCpp;
276267
s_server = odr::HttpServer(config);
277268
}
278269

279270
JNIEXPORT jobject JNICALL
280-
Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass clazz, jstring prefix, jobject options) {
271+
Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass clazz, jstring prefix,
272+
jobject options) {
281273
__android_log_print(ANDROID_LOG_INFO, "smn", "host file");
282274

283275
jclass resultClass = env->FindClass("at/tomtasche/reader/background/CoreWrapper$CoreResult");
@@ -286,6 +278,28 @@ Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass cla
286278

287279
jfieldID errorField = env->GetFieldID(resultClass, "errorCode", "I");
288280

281+
if (!s_server.has_value()) {
282+
env->SetIntField(result, errorField, -1);
283+
return result;
284+
}
285+
286+
s_server->clear();
287+
288+
jclass optionsClass = env->GetObjectClass(options);
289+
290+
std::optional<std::string> passwordCpp;
291+
jfieldID passwordField = env->GetFieldID(optionsClass, "password", "Ljava/lang/String;");
292+
auto password = (jstring) env->GetObjectField(options, passwordField);
293+
if (password != nullptr) {
294+
passwordCpp = convertString(env, password);
295+
}
296+
297+
jfieldID pagingField = env->GetFieldID(optionsClass, "paging", "Z");
298+
jboolean paging = env->GetBooleanField(options, pagingField);
299+
300+
jfieldID editableField = env->GetFieldID(optionsClass, "editable", "Z");
301+
jboolean editable = env->GetBooleanField(options, editableField);
302+
289303
jclass listClass = env->FindClass("java/util/List");
290304
jmethodID addMethod = env->GetMethodID(listClass, "add", "(Ljava/lang/Object;)Z");
291305

@@ -299,34 +313,56 @@ Java_at_tomtasche_reader_background_CoreWrapper_hostFile(JNIEnv *env, jclass cla
299313
std::string prefixCpp = convertString(env, prefix);
300314

301315
odr::DecodePreference decodePreference;
302-
decodePreference.engine_priority = {odr::DecoderEngine::poppler, odr::DecoderEngine::wvware, odr::DecoderEngine::odr};
316+
decodePreference.engine_priority = {odr::DecoderEngine::poppler, odr::DecoderEngine::wvware,
317+
odr::DecoderEngine::odr};
303318
odr::DecodedFile file = odr::open(inputPathCpp, decodePreference);
304319

320+
if (file.is_document_file()) {
321+
odr::DocumentFile document_file = file.document_file();
322+
if (document_file.password_encrypted()) {
323+
if (!passwordCpp.has_value() || !document_file.decrypt(passwordCpp.value())) {
324+
env->SetIntField(result, errorField, -2);
325+
return result;
326+
}
327+
}
328+
// TODO this will cause a second load
329+
s_document = document_file.document();
330+
}
331+
305332
odr::HtmlConfig htmlConfig;
306333
htmlConfig.embed_images = false;
307-
htmlConfig.embed_shipped_resources = false;
334+
htmlConfig.embed_shipped_resources = true;
335+
htmlConfig.relative_resource_paths = false;
336+
htmlConfig.text_document_margin = paging;
337+
htmlConfig.editable = editable;
308338

309339
try {
310-
odr::HtmlViews htmlViews = s_server->serve_file(file, prefixCpp, odr::HtmlConfig());
340+
odr::HtmlViews htmlViews = s_server->serve_file(file, prefixCpp, htmlConfig);
311341

312342
for (const auto &view: htmlViews) {
313-
if (file.is_document_file() &&
314-
file.document_file().document_type() != odr::DocumentType::text &&
315-
view.name() == "document") {
343+
__android_log_print(ANDROID_LOG_INFO, "smn", "view name=%s path=%s", view.name().c_str(), view.path().c_str());
344+
if (file.is_document_file() && (
345+
(((file.document_file().document_type() == odr::DocumentType::presentation) ||
346+
(file.document_file().document_type() == odr::DocumentType::drawing)) &&
347+
(view.name() != "document")) ||
348+
((file.document_file().document_type() == odr::DocumentType::spreadsheet) &&
349+
(view.name() == "document")))) {
316350
continue;
317351
}
318352

319353
jstring pageName = env->NewStringUTF(view.name().c_str());
320354
env->CallBooleanMethod(pageNames, addMethod, pageName);
321355

322-
std::string pagePathCpp = "http://localhost:29665/file/" + prefixCpp + "/" + view.path();
356+
std::string pagePathCpp =
357+
"http://localhost:29665/file/" + prefixCpp + "/" + view.path();
323358
jstring pagePath = env->NewStringUTF(pagePathCpp.c_str());
324359
env->CallBooleanMethod(pagePaths, addMethod, pagePath);
325360
}
326361
} catch (const std::exception &e) {
327362
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unhandled C++ exception: %s", e.what());
328363
} catch (...) {
329-
__android_log_print(ANDROID_LOG_ERROR, "smn", "Unhandled C++ exception without further information");
364+
__android_log_print(ANDROID_LOG_ERROR, "smn",
365+
"Unhandled C++ exception without further information");
330366
}
331367

332368
return result;

app/src/main/java/at/tomtasche/reader/background/CoreLoader.java

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public class CoreLoader extends FileLoader {
1616

1717
private final ConfigManager configManager;
1818

19-
private CoreWrapper lastCore;
2019
private CoreWrapper.CoreOptions lastCoreOptions;
2120

2221
private final boolean doOoxml;
@@ -37,7 +36,7 @@ public CoreLoader(Context context, ConfigManager configManager, boolean doOoxml,
3736
@Override
3837
public void initialize(FileLoaderListener listener, Handler mainHandler, Handler backgroundHandler, AnalyticsManager analyticsManager, CrashManager crashManager) {
3938
if (doHttp) {
40-
File serverCacheDir = new File(context.getCacheDir(), "core");
39+
File serverCacheDir = new File(context.getCacheDir(), "core/server");
4140
if (!serverCacheDir.mkdirs()) {
4241
Log.e("CoreLoader", "Failed to create cache directory for CoreWrapper server: " + serverCacheDir.getAbsolutePath());
4342
}
@@ -91,18 +90,6 @@ public void loadSync(Options options) {
9190
private void translate(Options options, Result result) throws Exception {
9291
File cachedFile = AndroidFileCache.getCacheFile(context, options.cacheUri);
9392

94-
if (lastCore != null) {
95-
lastCore.close();
96-
lastCore = null;
97-
}
98-
99-
CoreWrapper core = new CoreWrapper();
100-
try {
101-
lastCore = core;
102-
} catch (Throwable e) {
103-
crashManager.log(e);
104-
}
105-
10693
File cacheDirectory = AndroidFileCache.getCacheDirectory(cachedFile);
10794

10895
CoreWrapper.CoreOptions coreOptions = new CoreWrapper.CoreOptions();
@@ -169,7 +156,7 @@ public File retranslate(Options options, String htmlDiff) {
169156
return null; // TODO
170157
}
171158

172-
if (lastCore == null) {
159+
if (lastCoreOptions == null) {
173160
// necessary if fragment was destroyed in the meanwhile - meaning the Loader is reinstantiated
174161

175162
Result result = new Result();
@@ -191,7 +178,7 @@ public File retranslate(Options options, String htmlDiff) {
191178
lastCoreOptions.outputPath = tempFilePrefix.getPath();
192179

193180
try {
194-
CoreWrapper.CoreResult result = lastCore.backtranslate(lastCoreOptions, htmlDiff);
181+
CoreWrapper.CoreResult result = CoreWrapper.backtranslate(lastCoreOptions, htmlDiff);
195182

196183
return new File(result.outputPath);
197184
} catch (Throwable e) {
@@ -215,9 +202,6 @@ public void close() {
215202
httpThread = null;
216203
}
217204

218-
if (lastCore != null) {
219-
lastCore.close();
220-
lastCore = null;
221-
}
205+
CoreWrapper.close();
222206
}
223207
}

app/src/main/java/at/tomtasche/reader/background/CoreWrapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public static void initialize(Context context) {
3232
File pdf2htmlexDataDirectory = new File(assetsDirectory, "pdf2htmlex");
3333

3434
AssetExtractor ae = new AssetExtractor(context.getAssets());
35+
ae.setOverwrite();
3536
ae.extract(assetsDirectory, "odrcore");
3637
ae.extract(assetsDirectory, "fontconfig");
3738
ae.extract(assetsDirectory, "poppler");
@@ -130,7 +131,7 @@ public static void close() {
130131

131132
private static native void closeNative(CoreOptions options);
132133

133-
public static native void createServer(String outputPath);
134+
public static native void createServer(String cachePath);
134135

135136
public static native CoreResult hostFile(String prefix, CoreOptions options);
136137

0 commit comments

Comments
 (0)