diff --git a/.gitignore b/.gitignore index e21ed8219..72e3a3349 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ koreader-*.zip /.cproject /.project +koreader-arm-linux-androideabi koreader-arm-linux-gnueabi koreader-x86_64-linux-gnu diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..47e427f0b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +# Travis-CI Build for koreader +# see travis-ci.org for details + +language: c + +compiler: + - gcc + +env: + - EMULATE_READER=1 USE_NO_CCACHE=1 + +install: + - sudo apt-get install libsdl1.2-dev luarocks + - git clone https://github.com/Olivine-Labs/busted/ + - cd busted && git checkout v1.10.0 && sudo luarocks make && cd .. + +script: + - make fetchthirdparty + - make + - make testfront diff --git a/Makefile b/Makefile index fe4eb7008..dd71a9e49 100644 --- a/Makefile +++ b/Makefile @@ -36,17 +36,17 @@ ifdef EMULATE_READER # create symlink instead of copying files in development mode cd $(INSTALL_DIR)/koreader && \ ln -sf ../../$(KOR_BASE)/$(OUTPUT_DIR)/* . - # install front spec + # install front spec only for the emulator cd $(INSTALL_DIR)/koreader/spec && test -e front || \ ln -sf ../../../../spec ./front + cd $(INSTALL_DIR)/koreader/spec/front/unit && test -e data || \ + ln -sf ../../test ./data else cp -rfL $(KOR_BASE)/$(OUTPUT_DIR)/* $(INSTALL_DIR)/koreader/ endif for f in $(INSTALL_FILES); do \ ln -sf ../../$$f $(INSTALL_DIR)/koreader/; \ done - cd $(INSTALL_DIR)/koreader/spec/front/unit && test -e data || \ - ln -sf ../../test ./data # install plugins cp -r plugins/* $(INSTALL_DIR)/koreader/plugins/ cp -rpL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/ @@ -131,10 +131,16 @@ androidupdate: all cd $(INSTALL_DIR)/koreader && 7z a -l -mx=1 \ ../../$(ANDROID_LAUNCHER_DIR)/assets/module/koreader-g$(REVISION).7z * \ -x!resources/fonts -x!resources/icons/src -x!spec + $(MAKE) -C $(ANDROID_LAUNCHER_DIR) apk + cp $(ANDROID_LAUNCHER_DIR)/bin/NativeActivity-debug.apk \ + koreader-android-$(MACHINE)-$(VERSION).apk androiddev: androidupdate $(MAKE) -C $(ANDROID_LAUNCHER_DIR) dev +android-toolchain: + $(MAKE) -C $(KOR_BASE) android-toolchain + pot: $(XGETTEXT_BIN) reader.lua `find frontend -iname "*.lua"` \ `find plugins -iname "*.lua"` \ diff --git a/README.md b/README.md index c611c3640..27e1d5e28 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ KOReader [![Build Status][travis-icon]][travis-link] ======== -This is a document viewer application, originally created for usage on the +KOReader is a document viewer application, originally created for usage on the Kindle e-ink reader. It currently supports Kindle 5 (Touch), Kindle Paperwhite -and Kobo devices. Kindles need to be jailbroken in order to install the -application. Also, a kind of external launcher is needed. +, Kobo and Android devices. KOReader started as the KindlePDFViewer application, but it supports much more formats than PDF now. Among them are DJVU, FB2, EPUB, TXT, CBZ, HTML. KOReader is a frontend written in Lua and uses the API presented by the -KOReader-base framework. KOReader implements a GUI and is currently targeted -at Touch-based devices - for the classic user interface for button-driven +koreader-base framework. KOReader implements a GUI and is currently targeted +at touch-based devices - for the classic user interface for button-driven e-ink devices (like the Kindle 2, Kindle DX, Kindle 3, Kindle 4) see the KindlePDFviewer legacy project or - especially for the Kindle 4 - have a look at its fork Librerator. @@ -24,8 +23,8 @@ more about this project. Prerequisites ======== -Instructions about how to get and compile the source are intended for a \*nix -OS. Windows users are suggested to develop in a [Linux VM](http://www.howtogeek.com/howto/11287/how-to-run-ubuntu-in-windows-7-with-vmware-player/) or use Wubi. +Instructions about how to get and compile the source are intended for a linux +OS. Windows users are suggested to develop in a [Linux VM][linux-vm] or use Wubi. To get and compile the source you must have `patch`, `wget`, `unzip`, `git`, `autoconf`, `subversion` and `cmake` installed. Version of autoconf need to be greater than 2.64. @@ -35,7 +34,7 @@ Ubuntu users may need to run: sudo apt-get install build-essential libtool ``` -Cross toolchains are available to Ubuntu users through these commands: +Cross compile toolchains are available for Ubuntu users through these commands: ``` # for Kindle sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi @@ -43,9 +42,12 @@ sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf ``` +A recent version of Android SDK/NDK is needed in order to build Koreader for Android +devices. + You might also need SDL library packages if you want to compile and run Koreader on PC. Fedora users can install `SDL` and `SDL-devel`. -Ubuntu users probably have to run: +Ubuntu users probably need to run: ``` sudo apt-get install libsdl1.2-dev ``` @@ -66,19 +68,20 @@ Building & Running & Testing For real eink devices --------------------- -If you already done an emulator build, you must do: +If you have already built one package for a different target, remember to run +this command before you go further: ``` make clean ``` -To build for the Kindle: +To build installable package for Kindle: ``` -make kindleupdate +make TARGET=kindle kindleupdate ``` -To build for the Kobo: +To build installable package for Kobo: ``` -make TARGET_DEVICE=KOBO koboupdate +make TARGET=kobo koboupdate ``` To run, you must call the script reader.lua. Run it without arguments to see @@ -88,8 +91,31 @@ be in the same directory. You may checkout our [nightlybuild script][nb-script] to see how to build a package from scratch. +For Android devices +------------------- + +Make sure the "android" tool is in your PATH variable and the NDK variable +points to the root directory of the Android NDK. + +First, run this command to make a standalone android cross compiling toolchain +from NDK: +``` +make android-toolchain +``` + +Also, if you have already built a different target, remember to clear the source +code tree with: +``` +make clean +``` + +Then, build installable package for Android: +``` +make TARGET=android androidupdate +``` + For emulating ------------ +------------- If you already done a real device build, you must do: ``` @@ -157,4 +183,5 @@ http://ccache.samba.org [travis-icon]:https://travis-ci.org/koreader/koreader-base.png?branch=master [travis-link]:https://travis-ci.org/koreader/koreader-base [travis-conf]:https://github.com/koreader/koreader-base/blob/master/.travis.yml +[linux-vm]:http://www.howtogeek.com/howto/11287/how-to-run-ubuntu-in-windows-7-with-vmware-player/ diff --git a/android/luajit-launcher b/android/luajit-launcher index 3153b9269..b7b14ec4d 160000 --- a/android/luajit-launcher +++ b/android/luajit-launcher @@ -1 +1 @@ -Subproject commit 3153b92693a4a57cbe6e21d32f94b1f89e115633 +Subproject commit b7b14ec4d09f0a6330ce6b05ce9d4c8e6a6eb572 diff --git a/frontend/ui/data/koptoptions.lua b/frontend/ui/data/koptoptions.lua index fa3567504..e54f66308 100644 --- a/frontend/ui/data/koptoptions.lua +++ b/frontend/ui/data/koptoptions.lua @@ -73,6 +73,30 @@ local KoptOptions = { values = {1.0, 1.2, 1.4}, default_value = DKOPTREADER_CONFIG_LINE_SPACING, }, + { + name = "max_columns", + name_text = S.COLUMNS, + item_icons = { + "resources/icons/appbar.column.one.png", + "resources/icons/appbar.column.two.png", + "resources/icons/appbar.column.three.png", + }, + values = {1,2,3}, + default_value = DKOPTREADER_CONFIG_MAX_COLUMNS, + }, + { + name = "justification", + name_text = S.TEXT_ALIGN, + item_icons = { + "resources/icons/appbar.align.auto.png", + "resources/icons/appbar.align.left.png", + "resources/icons/appbar.align.center.png", + "resources/icons/appbar.align.right.png", + "resources/icons/appbar.align.justify.png", + }, + values = {-1,0,1,2,3}, + default_value = DKOPTREADER_CONFIG_JUSTIFICATION, + }, } }, { @@ -177,30 +201,6 @@ local KoptOptions = { values={0.5, 1.0, 1.5}, default_value = DKOPTREADER_CONFIG_RENDER_QUALITY, }, - { - name = "max_columns", - name_text = S.COLUMNS, - item_icons = { - "resources/icons/appbar.column.one.png", - "resources/icons/appbar.column.two.png", - "resources/icons/appbar.column.three.png", - }, - values = {1,2,3}, - default_value = DKOPTREADER_CONFIG_MAX_COLUMNS, - }, - { - name = "justification", - name_text = S.TEXT_ALIGN, - item_icons = { - "resources/icons/appbar.align.auto.png", - "resources/icons/appbar.align.left.png", - "resources/icons/appbar.align.center.png", - "resources/icons/appbar.align.right.png", - "resources/icons/appbar.align.justify.png", - }, - values = {-1,0,1,2,3}, - default_value = DKOPTREADER_CONFIG_JUSTIFICATION, - }, { name = "defect_size", name_text = S.DEFECT_SIZE, diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index 9c835f4e6..e2ad13ff0 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -56,7 +56,7 @@ end function MenuBarItem:invert(invert) self[1].invert = invert - UIManager:setDirty(self.config) + UIManager:setDirty(self.config, "partial") end local OptionTextItem = InputContainer:new{} diff --git a/koreader-base b/koreader-base index 356557819..adfd78e69 160000 --- a/koreader-base +++ b/koreader-base @@ -1 +1 @@ -Subproject commit 3565578196c001d5a3099d3fa9a754e4c2832403 +Subproject commit adfd78e69146657566f18fa8815ff0028b1f4e21 diff --git a/spec/unit/benchmark_spec.lua b/spec/unit/benchmark_spec.lua index f4ad90971..23ab4b9de 100644 --- a/spec/unit/benchmark_spec.lua +++ b/spec/unit/benchmark_spec.lua @@ -1,5 +1,4 @@ require "defaults" -require "libs/libkoreader-luagettext" package.path = "?.lua;common/?.lua;frontend/?.lua" package.cpath = "?.so;common/?.so;/usr/lib/lua/?.so" @@ -8,12 +7,12 @@ einkfb = require("ffi/framebuffer") -- do not show SDL window einkfb.dummy = true Blitbuffer = require("ffi/blitbuffer") -util = require("ffi/util") local Screen = require("ui/screen") local DocSettings = require("docsettings") G_reader_settings = DocSettings:open(".reader") local DocumentRegistry = require("document/documentregistry") +local util = require("ffi/util") local DEBUG = require("dbg") -- screen should be inited for crengine @@ -33,7 +32,7 @@ end describe("PDF rendering benchmark", function() local sample_pdf = "spec/front/unit/data/sample.pdf" local doc = DocumentRegistry:openDocument(sample_pdf) - for pageno = 1, doc.info.number_of_pages do + for pageno = 1, math.min(10, doc.info.number_of_pages) do local secs, usecs = util.gettime() assert.truthy(doc:renderPage(pageno, nil, 1, 0, 1.0, 0)) local nsecs, nusecs = util.gettime() @@ -43,3 +42,17 @@ describe("PDF rendering benchmark", function() doc:close() end) +describe("PDF reflowing benchmark", function() + local sample_pdf = "spec/front/unit/data/sample.pdf" + local doc = DocumentRegistry:openDocument(sample_pdf) + doc.configurable.text_wrap = 1 + for pageno = 1, math.min(10, doc.info.number_of_pages) do + local secs, usecs = util.gettime() + assert.truthy(doc:renderPage(pageno, nil, 1, 0, 1.0, 0)) + local nsecs, nusecs = util.gettime() + local dur = nsecs - secs + (nusecs - usecs) / 1000000 + logDuration("pdf_reflowing.log", pageno, dur) + end + doc:close() +end) + diff --git a/spec/unit/cache_spec.lua b/spec/unit/cache_spec.lua new file mode 100644 index 000000000..f32ff3f8e --- /dev/null +++ b/spec/unit/cache_spec.lua @@ -0,0 +1,57 @@ +require "defaults" +package.path = "?.lua;common/?.lua;frontend/?.lua" +package.cpath = "?.so;common/?.so;/usr/lib/lua/?.so" + +require "libs/libkoreader-lfs" +-- global einkfb for Screen +einkfb = require("ffi/framebuffer") +-- do not show SDL window +einkfb.dummy = true +Blitbuffer = require("ffi/blitbuffer") + +local Screen = require("ui/screen") +local DocSettings = require("docsettings") +G_reader_settings = DocSettings:open(".reader") +local DocumentRegistry = require("document/documentregistry") +local Cache = require("cache") +local DEBUG = require("dbg") +--DEBUG:turnOn() + +-- screen should be inited for crengine +Screen:init() + +describe("Cache module", function() + local sample_pdf = "spec/front/unit/data/sample.pdf" + local doc = DocumentRegistry:openDocument(sample_pdf) + it("should clear cache", function() + Cache:clear() + end) + it("should serialize blitbuffer", function() + for pageno = 1, math.min(10, doc.info.number_of_pages) do + doc:renderPage(pageno, nil, 1, 0, 1.0, 0) + Cache:serialize() + end + Cache:clear() + end) + it("should deserialize blitbuffer", function() + for pageno = 1, math.min(10, doc.info.number_of_pages) do + doc:hintPage(pageno, 1, 0, 1.0, 0) + end + Cache:clear() + end) + it("should serialize koptcontext", function() + doc.configurable.text_wrap = 1 + for pageno = 1, math.min(10, doc.info.number_of_pages) do + doc:renderPage(pageno, nil, 1, 0, 1.0, 0) + doc:getPageDimensions(pageno) + Cache:serialize() + end + Cache:clear() + end) + it("should deserialize koptcontext", function() + for pageno = 1, math.min(10, doc.info.number_of_pages) do + doc:renderPage(pageno, nil, 1, 0, 1.0, 0) + end + Cache:clear() + end) +end) diff --git a/spec/unit/document_spec.lua b/spec/unit/document_spec.lua index 0ea747acd..b4cc77bf0 100644 --- a/spec/unit/document_spec.lua +++ b/spec/unit/document_spec.lua @@ -1,5 +1,4 @@ require "defaults" -require "libs/libkoreader-luagettext" package.path = "?.lua;common/?.lua;frontend/?.lua" package.cpath = "?.so;common/?.so;/usr/lib/lua/?.so" diff --git a/test/sample.pdf b/test/sample.pdf new file mode 100644 index 000000000..33fc90838 Binary files /dev/null and b/test/sample.pdf differ