-
Notifications
You must be signed in to change notification settings - Fork 161
Add a LVContainerTransform for interaction between koreader and crengine #2477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -417,6 +417,85 @@ typedef struct CreDocument { | |
| ldomDocument *dom_doc; | ||
| } CreDocument; | ||
|
|
||
| class LVContainerTransform : public LVContainer | ||
| { | ||
| lua_State * _L; | ||
| int _transform_ref; | ||
| LVContainerRef _container; | ||
|
|
||
| LVStreamRef openTransformedEntry(lString32 path) | ||
| { | ||
| int top = lua_gettop(_L); | ||
| lua_rawgeti(_L, LUA_REGISTRYINDEX, _transform_ref); | ||
| lua_getfield(_L, -1, "transformEntry"); | ||
| if (lua_isnil(_L, -1)) { | ||
| lua_settop(_L, top); | ||
| return LVStreamRef(); | ||
| } | ||
|
|
||
| lua_insert(_L, -2); | ||
| lString8 path8 = UnicodeToUtf8(path); | ||
| lua_pushstring(_L, path8.c_str()); | ||
| if (lua_pcall(_L, 2, 1, 0) != 0) { | ||
| CRLog::error("LVContainerTransform: transformEntry failed: %s", lua_tostring(_L, -1)); | ||
| lua_settop(_L, top); | ||
| return LVStreamRef(); | ||
| } | ||
| if (lua_isnil(_L, -1)) { | ||
| lua_settop(_L, top); | ||
| return LVStreamRef(); | ||
| } | ||
|
|
||
| size_t data_size = 0; | ||
| const char * data = lua_tolstring(_L, -1, &data_size); | ||
| if (!data) { | ||
| CRLog::error("LVContainerTransform: transformEntry() must return nil or a byte string"); | ||
| lua_settop(_L, top); | ||
| return LVStreamRef(); | ||
| } | ||
|
|
||
| LVStreamRef stream = LVCreateMemoryStream((void*)data, (int)data_size, true); | ||
| if (!stream.isNull()) | ||
| stream->SetName(path.c_str()); | ||
| lua_settop(_L, top); | ||
| return stream; | ||
| } | ||
|
|
||
| public: | ||
| LVContainerTransform(lua_State * L, int transform_ref, LVContainerRef container) : | ||
| _L(L), _transform_ref(transform_ref), _container(container) { } | ||
|
|
||
| virtual ~LVContainerTransform() { | ||
| if (_transform_ref != LUA_NOREF) { | ||
| luaL_unref(_L, LUA_REGISTRYINDEX, _transform_ref); | ||
| _transform_ref = LUA_NOREF; | ||
| } | ||
| } | ||
|
|
||
| virtual LVContainer * GetParentContainer() { return _container->GetParentContainer(); } | ||
| virtual lverror_t GetSize(lvsize_t * pSize) { return _container->GetSize(pSize); } | ||
| virtual const LVContainerItemInfo * GetObjectInfo(int index) { return _container->GetObjectInfo(index); } | ||
| virtual const LVContainerItemInfo * GetObjectInfo(lString32 name) { return _container->GetObjectInfo(name); } | ||
| virtual int GetObjectCount() const { return _container->GetObjectCount(); } | ||
|
|
||
| virtual LVStreamRef OpenStream(const lChar32 * fname, lvopen_mode_t mode) | ||
| { | ||
| if (!fname) | ||
| return LVStreamRef(); | ||
|
|
||
| if (mode == LVOM_READ) { | ||
| LVStreamRef transformed = openTransformedEntry(lString32(fname)); | ||
| if (!transformed.isNull()) | ||
| return transformed; | ||
| } | ||
|
|
||
| return _container->OpenStream(fname, mode); | ||
| } | ||
|
Comment on lines
+481
to
+493
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like it (and similar) as condensed as: virtual LVStreamRef OpenStream(const lChar32 * fname, lvopen_mode_t mode) {
if (!fname)
return LVStreamRef();
if (mode == LVOM_READ) {
LVStreamRef transformed = openTransformedEntry(lString32(fname));
if (!transformed.isNull())
return transformed;
}
return _container->OpenStream(fname, mode);
} |
||
|
|
||
| virtual const lChar32 * GetName() { return _container->GetName(); } | ||
| virtual void SetName(const lChar32 * name) { _container->SetName(name); } | ||
| }; | ||
|
|
||
| static int setCallback(lua_State *L) { | ||
| CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument"); | ||
| if ( cre_callback_forwarder == NULL ) { | ||
|
|
@@ -704,6 +783,41 @@ static int loadDocument(lua_State *L) { | |
| return 1; | ||
| } | ||
|
|
||
| static int loadEpubWithEntryTransform(lua_State *L) { | ||
| CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument"); | ||
| const char *file_name = luaL_checkstring(L, 2); | ||
| luaL_checktype(L, 3, LUA_TTABLE); | ||
| bool only_metadata = false; | ||
| if (lua_isboolean(L, 4)) { | ||
| only_metadata = lua_toboolean(L, 4); | ||
| } | ||
|
|
||
| lString32 file_name32 = LocalToUnicode(lString8(file_name)); | ||
|
Comment on lines
+786
to
+795
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add some introduction comment, what it is for, that it is not used by KOReader but available to plugins that would like to do xyz, what it allows, etc... |
||
| LVStreamRef stream = LVOpenFileStream(file_name32.c_str(), LVOM_READ); | ||
| if (stream.isNull()) { | ||
| lua_pushboolean(L, false); | ||
| return 1; | ||
| } | ||
|
|
||
| LVContainerRef archive = LVOpenArchieve(stream); | ||
| if (archive.isNull()) { | ||
| lua_pushboolean(L, false); | ||
| return 1; | ||
| } | ||
|
|
||
| lua_pushvalue(L, 3); | ||
| int transform_ref = luaL_ref(L, LUA_REGISTRYINDEX); | ||
| LVContainerRef container(new LVContainerTransform(L, transform_ref, archive)); | ||
|
Comment on lines
+808
to
+810
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that our arg 3 ? Explain what it is and how it will be used. |
||
|
|
||
| doc->text_view->LoadEpubDocument(container, file_name32.c_str(), only_metadata); | ||
| doc->dom_doc = doc->text_view->getDocument(); | ||
|
|
||
| bool loaded = false; | ||
| if (doc->dom_doc) { loaded = true ;} | ||
| lua_pushboolean(L, loaded); | ||
| return 1; | ||
| } | ||
|
|
||
| static int renderDocument(lua_State *L) { | ||
| CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument"); | ||
| doc->text_view->Render(); | ||
|
|
@@ -4360,6 +4474,7 @@ static const struct luaL_Reg cre_func[] = { | |
|
|
||
| static const struct luaL_Reg credocument_meth[] = { | ||
| {"loadDocument", loadDocument}, | ||
| {"loadEpubWithEntryTransform", loadEpubWithEntryTransform}, | ||
| {"renderDocument", renderDocument}, | ||
| {"requestRender", requestRender}, | ||
| /*--- get methods ---*/ | ||
|
|
||
| +2 −2 | .github/workflows/build.yml | |
| +3 −1 | .gitignore | |
| +4 −0 | crengine/include/epubfmt.h | |
| +1 −1 | crengine/include/lvarray.h | |
| +2 −0 | crengine/include/lvdocview.h | |
| +1 −0 | crengine/include/lvfntman.h | |
| +16 −7 | crengine/include/lvref.h | |
| +3 −1 | crengine/include/lvrefcache.h | |
| +17 −4 | crengine/src/epubfmt.cpp | |
| +5 −11 | crengine/src/hyphman.cpp | |
| +76 −0 | crengine/src/lvdocview.cpp | |
| +1 −1 | crengine/src/lvfntman.cpp | |
| +1 −1 | crengine/src/lvimg.cpp | |
| +1 −1 | crengine/src/lvrend.cpp | |
| +1 −9 | crengine/src/lvstream.cpp | |
| +4 −3 | crengine/src/lvstring.cpp | |
| +2 −2 | crengine/src/lvstsheet.cpp | |
| +1 −1 | crengine/src/lvtextfm.cpp | |
| +2 −2 | crengine/src/lvtinydom.cpp | |
| +2 −2 | crengine/src/lvxml.cpp | |
| +0 −1 | thirdparty/antiword/options.c | |
| +0 −2 | thirdparty/chmlib/src/chm_lib.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add some introduction comment, what it is for, that it is not used by KOReader but available to plugins that would like to do xyz, what it allows, etc...