2
0
mirror of https://github.com/koreader/koreader synced 2024-11-18 03:25:46 +00:00

Merge pull request #292 from houqp/new_ui_code

merge latest changes from master branch
This commit is contained in:
Dobrica Pavlinušić 2012-09-18 00:24:42 -07:00
commit 4582e471be
10 changed files with 279 additions and 127 deletions

View File

@ -8,7 +8,7 @@ DJVUDIR=djvulibre
KPVCRLIBDIR=kpvcrlib KPVCRLIBDIR=kpvcrlib
CRENGINEDIR=$(KPVCRLIBDIR)/crengine CRENGINEDIR=$(KPVCRLIBDIR)/crengine
FREETYPEDIR=$(MUPDFDIR)/thirdparty/freetype-2.4.9 FREETYPEDIR=$(MUPDFDIR)/thirdparty/freetype-2.4.10
LFSDIR=luafilesystem LFSDIR=luafilesystem
# must point to directory with *.ttf fonts for crengine # must point to directory with *.ttf fonts for crengine
@ -90,7 +90,7 @@ LUALIB := $(LUADIR)/src/libluajit.a
all:kpdfview all:kpdfview
kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o drawcontext.o input.o util.o ft.o lfs.o mupdfimg.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) djvu.o $(DJVULIBS) cre.o $(CRENGINELIBS) kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o drawcontext.o input.o util.o ft.o lfs.o mupdfimg.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) djvu.o $(DJVULIBS) cre.o $(CRENGINELIBS)
$(CC) -lm -ldl -lpthread $(EMU_LDFLAGS) $(DYNAMICLIBSTDCPP) \ $(CC) \
kpdfview.o \ kpdfview.o \
einkfb.o \ einkfb.o \
pdf.o \ pdf.o \
@ -109,7 +109,7 @@ kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o drawcontext.o input.o util.o ft
cre.o \ cre.o \
$(CRENGINELIBS) \ $(CRENGINELIBS) \
$(STATICLIBSTDCPP) \ $(STATICLIBSTDCPP) \
-o kpdfview -o kpdfview -lm -ldl -lpthread $(EMU_LDFLAGS) $(DYNAMICLIBSTDCPP)
slider_watcher: slider_watcher.c slider_watcher: slider_watcher.c
$(CC) $(CFLAGS) $< -o $@ $(CC) $(CFLAGS) $< -o $@
@ -211,6 +211,8 @@ thirdparty: $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) $(CRENGINELIBS)
INSTALL_DIR=kindlepdfviewer INSTALL_DIR=kindlepdfviewer
LUA_FILES=reader.lua
VERSION?=$(shell git rev-parse --short HEAD) VERSION?=$(shell git rev-parse --short HEAD)
customupdate: all customupdate: all
# ensure that build binary is for ARM # ensure that build binary is for ARM
@ -219,7 +221,7 @@ customupdate: all
-rm kindlepdfviewer-$(VERSION).zip -rm kindlepdfviewer-$(VERSION).zip
rm -Rf $(INSTALL_DIR) rm -Rf $(INSTALL_DIR)
mkdir $(INSTALL_DIR) mkdir $(INSTALL_DIR)
cp -p README.TXT COPYING kpdfview *.lua $(INSTALL_DIR) cp -p README.md COPYING kpdfview $(LUA_FILES) $(INSTALL_DIR)
mkdir $(INSTALL_DIR)/data mkdir $(INSTALL_DIR)/data
cp -rpL data/*.css $(INSTALL_DIR)/data cp -rpL data/*.css $(INSTALL_DIR)/data
cp -rpL fonts $(INSTALL_DIR) cp -rpL fonts $(INSTALL_DIR)

View File

@ -1,70 +0,0 @@
KindlePDFViewer
===============
This is a PDF viewer application, created for usage on the Kindle e-ink reader.
It is currently restricted to 4bpp inverse grayscale displays. It's using the
muPDF library (see http://mupdf.com/) and its UI is scripted using Lua (see
http://www.lua.org/).
The application is licensed under the GPLv3 (see COPYING file).
Building
========
Follow these steps:
- install muPDF sources into subfolder "mupdf"
- install muPDF third-party sources (see muPDF homepage) into a new subfolder
"mupdf/thirdparty"
- install libDjvuLibre sources into subfolder "djvulibre"
- install CREngine sources into subfolder "kpvcrlib/crengine"
- install LuaJit sources into subfolder "luajit-2.0"
=> note that there's a make target to do all the above. You need wget, unzip and git
installed. Then just run "make fetchthirdparty".
- adapt Makefile to your needs
- run "make thirdparty". This will build MuPDF (plus the libraries it depends
on) and Lua.
- run "make". This will build the kpdfview application
Running
=======
The user interface (or what's there yet) is scripted in Lua. See "reader.lua".
It uses the Linux feature to run scripts by using a corresponding line at its
start.
So you might just call that script. Note that the script and the kpdfview
binary currently must be in the same directory.
You would then just call reader.lua, giving the document file path as its first
argument. Run reader.lua without arguments to see usage notes.
The reader.lua script can also show a file chooser: it will do this when you
call it with a directory (instead of a file) as first argument.
Device emulation
================
The code also features a device emulation. You need SDL headers and library
for this. It allows to develop on a standard PC and saves precious development
time. It might also compose the most unfriendly desktop PDF reader, depending
on your view.
To build in "emulation mode", you need to run make like this:
make clean cleanthirdparty
EMULATE_READER=1 make thirdparty kpdfview
And run the emulator like this:
./reader.lua /PATH/TO/PDF.pdf
By default emulation will provide DXG resolution of 824*1200. It can be
specified at compile time, this is example for Kindle 3:
EMULATE_READER_W=600 EMULATE_READER_H=800 EMULATE_READER=1 make kpdfview

85
README.md Normal file
View File

@ -0,0 +1,85 @@
KindlePDFViewer
===============
This is a PDF viewer application, created for usage on the Kindle e-ink reader.
It currently supports Kindle 2, DXG, 3 and 4, but not Touch. It's using the
muPDF library (see http://mupdf.com/), djvulibre library, CREngine library and
its UI is scripted using Lua (see http://www.lua.org/).
The application is licensed under the GPLv3 (see COPYING file).
Building
========
Follow these steps:
* fetch thirdparty sources
* manually fetch all the thirdparty sources:
* install muPDF sources into subfolder "mupdf"
* install muPDF third-party sources (see muPDF homepage) into a new
subfolder "mupdf/thirdparty"
* install libDjvuLibre sources into subfolder "djvulibre"
* install CREngine sources into subfolder "kpvcrlib/crengine"
* install LuaJit sources into subfolder "luajit-2.0"
* automatically fetch thirdparty sources with Makefile:
* make sure you have wget, unzip and git installed
* run `make fetchthirdparty`.
* adapt Makefile to your needs
* run `make thirdparty`. This will build MuPDF (plus the libraries it depends
on), libDjvuLibre, CREngine and Lua.
* run `make`. This will build the kpdfview application
Running
=======
The user interface (or what's there yet) is scripted in Lua. See "reader.lua".
It uses the Linux feature to run scripts by using a corresponding line at its
start.
So you might just call that script. Note that the script and the kpdfview
binary currently must be in the same directory.
You would then just call reader.lua, giving the document file path, or any
directory path, as its first argument. Run reader.lua without arguments to see
usage notes. The reader.lua script can also show a file chooser: it will do
this when you call it with a directory (instead of a file) as first argument.
Device emulation
================
The code also features a device emulation. You need SDL headers and library
for this. It allows to develop on a standard PC and saves precious development
time. It might also compose the most unfriendly desktop PDF reader, depending
on your view.
If you are using Ubuntu, simply install `libsdl-dev1.2` package.
To build in "emulation mode", you need to run make like this:
make clean cleanthirdparty
EMULATE_READER=1 make thirdparty kpdfview
And run the emulator like this:
```
./reader.lua /PATH/TO/PDF.pdf
```
or:
```
./reader.lua /ANY/PATH
```
By default emulation will provide DXG resolution of 824*1200. It can be
specified at compile time, this is example for Kindle 3:
```
EMULATE_READER_W=600 EMULATE_READER_H=800 EMULATE_READER=1 make kpdfview
```

77
cre.cpp
View File

@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define DEBUG_CRENGINE 0
extern "C" { extern "C" {
#include "blitbuffer.h" #include "blitbuffer.h"
@ -32,6 +33,13 @@ typedef struct CreDocument {
ldomDocument *dom_doc; ldomDocument *dom_doc;
} CreDocument; } CreDocument;
static int initCache(lua_State *L) {
int cache_size = luaL_optint(L, 1, (2 << 20) * 64); // 64Mb on disk cache for DOM
ldomDocCache::init(lString16("./cr3cache"), cache_size);
return 0;
}
static int openDocument(lua_State *L) { static int openDocument(lua_State *L) {
const char *file_name = luaL_checkstring(L, 1); const char *file_name = luaL_checkstring(L, 1);
@ -443,7 +451,75 @@ static int registerFont(lua_State *L) {
return 0; return 0;
} }
// ported from Android UI kpvcrlib/crengine/android/jni/docview.cpp
static int findText(lua_State *L) {
CreDocument *doc = (CreDocument*) luaL_checkudata(L, 1, "credocument");
const char *l_pattern = luaL_checkstring(L, 2);
lString16 pattern = lString16(l_pattern);
int origin = luaL_checkint(L, 3);
bool reverse = luaL_checkint(L, 4);
bool caseInsensitive = luaL_checkint(L, 5);
if ( pattern.empty() )
return 0;
LVArray<ldomWord> words;
lvRect rc;
doc->text_view->GetPos( rc );
int pageHeight = rc.height();
int start = -1;
int end = -1;
if ( reverse ) {
// reverse
if ( origin == 0 ) {
// from end current page to first page
end = rc.bottom;
} else if ( origin == -1 ) {
// from last page to end of current page
start = rc.bottom;
} else { // origin == 1
// from prev page to first page
end = rc.top;
}
} else {
// forward
if ( origin == 0 ) {
// from current page to last page
start = rc.top;
} else if ( origin == -1 ) {
// from first page to current page
end = rc.top;
} else { // origin == 1
// from next page to last
start = rc.bottom;
}
}
CRLog::debug("CRViewDialog::findText: Current page: %d .. %d", rc.top, rc.bottom);
CRLog::debug("CRViewDialog::findText: searching for text '%s' from %d to %d origin %d", LCSTR(pattern), start, end, origin );
if ( doc->text_view->getDocument()->findText( pattern, caseInsensitive, reverse, start, end, words, 200, pageHeight ) ) {
CRLog::debug("CRViewDialog::findText: pattern found");
doc->text_view->clearSelection();
doc->text_view->selectWords( words );
ldomMarkedRangeList * ranges = doc->text_view->getMarkedRanges();
if ( ranges ) {
if ( ranges->length()>0 ) {
int pos = ranges->get(0)->start.y;
//doc->text_view->SetPos(pos); // commented out not to mask lua code which does the same
CRLog::debug("# SetPos = %d", pos);
lua_pushinteger(L, ranges->length()); // results found
lua_pushinteger(L, pos);
return 2;
}
}
return 0;
}
CRLog::debug("CRViewDialog::findText: pattern not found");
return 0;
}
static const struct luaL_Reg cre_func[] = { static const struct luaL_Reg cre_func[] = {
{"initCache", initCache},
{"openDocument", openDocument}, {"openDocument", openDocument},
{"getFontFaces", getFontFaces}, {"getFontFaces", getFontFaces},
{"getGammaIndex", getGammaIndex}, {"getGammaIndex", getGammaIndex},
@ -480,6 +556,7 @@ static const struct luaL_Reg credocument_meth[] = {
//{"cursorLeft", cursorLeft}, //{"cursorLeft", cursorLeft},
//{"cursorRight", cursorRight}, //{"cursorRight", cursorRight},
{"drawCurrentView", drawCurrentView}, {"drawCurrentView", drawCurrentView},
{"findText", findText},
{"close", closeDocument}, {"close", closeDocument},
{"__gc", closeDocument}, {"__gc", closeDocument},
{NULL, NULL} {NULL, NULL}

149
djvu.c
View File

@ -15,6 +15,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <math.h>
#include <libdjvu/miniexp.h> #include <libdjvu/miniexp.h>
#include <libdjvu/ddjvuapi.h> #include <libdjvu/ddjvuapi.h>
@ -30,6 +31,7 @@
typedef struct DjvuDocument { typedef struct DjvuDocument {
ddjvu_context_t *context; ddjvu_context_t *context;
ddjvu_document_t *doc_ref; ddjvu_document_t *doc_ref;
ddjvu_format_t *pixelformat;
} DjvuDocument; } DjvuDocument;
typedef struct DjvuPage { typedef struct DjvuPage {
@ -76,9 +78,9 @@ static int openDocument(lua_State *L) {
luaL_getmetatable(L, "djvudocument"); luaL_getmetatable(L, "djvudocument");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
doc->context = ddjvu_context_create("DJVUReader"); doc->context = ddjvu_context_create("kindlepdfviewer");
if (! doc->context) { if (! doc->context) {
return luaL_error(L, "cannot create context."); return luaL_error(L, "cannot create context");
} }
printf("## cache_size = %d\n", cache_size); printf("## cache_size = %d\n", cache_size);
@ -88,9 +90,18 @@ static int openDocument(lua_State *L) {
while (! ddjvu_document_decoding_done(doc->doc_ref)) while (! ddjvu_document_decoding_done(doc->doc_ref))
handle(L, doc->context, True); handle(L, doc->context, True);
if (! doc->doc_ref) { if (! doc->doc_ref) {
return luaL_error(L, "cannot open DJVU file <%s>", filename); return luaL_error(L, "cannot open DjVu file <%s>", filename);
} }
doc->pixelformat = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, NULL);
if (! doc->pixelformat) {
return luaL_error(L, "cannot create DjVu pixelformat for <%s>", filename);
}
ddjvu_format_set_row_order(doc->pixelformat, 1);
ddjvu_format_set_y_direction(doc->pixelformat, 1);
/* dithering bits <8 are ignored by djvulibre */
/* ddjvu_format_set_ditherbits(doc->pixelformat, 4); */
return 1; return 1;
} }
@ -98,14 +109,18 @@ static int closeDocument(lua_State *L) {
DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
// should be save if called twice // should be save if called twice
if(doc->doc_ref != NULL) { if (doc->doc_ref != NULL) {
ddjvu_document_release(doc->doc_ref); ddjvu_document_release(doc->doc_ref);
doc->doc_ref = NULL; doc->doc_ref = NULL;
} }
if(doc->context != NULL) { if (doc->context != NULL) {
ddjvu_context_release(doc->context); ddjvu_context_release(doc->context);
doc->context = NULL; doc->context = NULL;
} }
if (doc->pixelformat != NULL) {
ddjvu_format_release(doc->pixelformat);
doc->pixelformat = NULL;
}
return 0; return 0;
} }
@ -177,7 +192,7 @@ static int openPage(lua_State *L) {
DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
int pageno = luaL_checkint(L, 2); int pageno = luaL_checkint(L, 2);
if(pageno < 1 || pageno > ddjvu_document_get_pagenum(doc->doc_ref)) { if (pageno < 1 || pageno > ddjvu_document_get_pagenum(doc->doc_ref)) {
return luaL_error(L, "cannot open page #%d, out of range (1-%d)", pageno, ddjvu_document_get_pagenum(doc->doc_ref)); return luaL_error(L, "cannot open page #%d, out of range (1-%d)", pageno, ddjvu_document_get_pagenum(doc->doc_ref));
} }
@ -185,18 +200,18 @@ static int openPage(lua_State *L) {
luaL_getmetatable(L, "djvupage"); luaL_getmetatable(L, "djvupage");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
/* djvulibre counts page starts form 0 */ /* djvulibre counts page starts from 0 */
page->page_ref = ddjvu_page_create_by_pageno(doc->doc_ref, pageno - 1); page->page_ref = ddjvu_page_create_by_pageno(doc->doc_ref, pageno - 1);
while (! ddjvu_page_decoding_done(page->page_ref)) while (! ddjvu_page_decoding_done(page->page_ref))
handle(L, doc->context, TRUE); handle(L, doc->context, TRUE);
if(! page->page_ref) { if (! page->page_ref) {
return luaL_error(L, "cannot open page #%d", pageno); return luaL_error(L, "cannot open page #%d", pageno);
} }
page->doc = doc; page->doc = doc;
page->num = pageno; page->num = pageno;
/* djvulibre counts page starts form 0 */ /* djvulibre counts page starts from 0 */
while((r=ddjvu_document_get_pageinfo(doc->doc_ref, pageno - 1, while((r=ddjvu_document_get_pageinfo(doc->doc_ref, pageno - 1,
&(page->info)))<DDJVU_JOB_OK) &(page->info)))<DDJVU_JOB_OK)
handle(L, doc->context, TRUE); handle(L, doc->context, TRUE);
@ -229,6 +244,23 @@ static int getUsedBBox(lua_State *L) {
return 4; return 4;
} }
static int getOriginalPageSize(lua_State *L) {
DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
int pageno = luaL_checkint(L, 2);
ddjvu_status_t r;
ddjvu_pageinfo_t info;
while ((r=ddjvu_document_get_pageinfo(
doc->doc_ref, pageno-1, &info))<DDJVU_JOB_OK) {
handle(L, doc->context, TRUE);
}
lua_pushnumber(L, info.width);
lua_pushnumber(L, info.height);
return 2;
}
/* /*
* Return a table like following: * Return a table like following:
@ -254,6 +286,17 @@ static int getPageText(lua_State *L) {
DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument");
int pageno = luaL_checkint(L, 2); int pageno = luaL_checkint(L, 2);
/* get page height for coordinates transform */
ddjvu_pageinfo_t info;
ddjvu_status_t r;
while ((r=ddjvu_document_get_pageinfo(
doc->doc_ref, pageno-1, &info))<DDJVU_JOB_OK) {
handle(L, doc->context, TRUE);
}
if (r>=DDJVU_JOB_FAILED)
return luaL_error(L, "cannot get page #%d information", pageno);
/* start retrieving page text */
miniexp_t sexp, se_line, se_word; miniexp_t sexp, se_line, se_word;
int i = 1, j = 1, counter_l = 1, counter_w=1, int i = 1, j = 1, counter_l = 1, counter_w=1,
nr_line = 0, nr_word = 0; nr_line = 0, nr_word = 0;
@ -277,7 +320,7 @@ static int getPageText(lua_State *L) {
/* retrive one line entry */ /* retrive one line entry */
se_line = miniexp_nth(i, sexp); se_line = miniexp_nth(i, sexp);
nr_word = miniexp_length(se_line); nr_word = miniexp_length(se_line);
if(nr_word == 0) { if (nr_word == 0) {
continue; continue;
} }
@ -291,16 +334,18 @@ static int getPageText(lua_State *L) {
lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_line))); lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_line)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "y0"); lua_pushstring(L, "y1");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(2, se_line))); lua_pushnumber(L,
info.height - miniexp_to_int(miniexp_nth(2, se_line)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "x1"); lua_pushstring(L, "x1");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_line))); lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_line)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "y1"); lua_pushstring(L, "y0");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(4, se_line))); lua_pushnumber(L,
info.height - miniexp_to_int(miniexp_nth(4, se_line)));
lua_settable(L, -3); lua_settable(L, -3);
/* now loop through each word in the line */ /* now loop through each word in the line */
@ -324,16 +369,18 @@ static int getPageText(lua_State *L) {
lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_word))); lua_pushnumber(L, miniexp_to_int(miniexp_nth(1, se_word)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "y0"); lua_pushstring(L, "y1");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(2, se_word))); lua_pushnumber(L,
info.height - miniexp_to_int(miniexp_nth(2, se_word)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "x1"); lua_pushstring(L, "x1");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_word))); lua_pushnumber(L, miniexp_to_int(miniexp_nth(3, se_word)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "y1"); lua_pushstring(L, "y0");
lua_pushnumber(L, miniexp_to_int(miniexp_nth(4, se_word))); lua_pushnumber(L,
info.height - miniexp_to_int(miniexp_nth(4, se_word)));
lua_settable(L, -3); lua_settable(L, -3);
lua_pushstring(L, "word"); lua_pushstring(L, "word");
@ -354,8 +401,8 @@ static int getPageText(lua_State *L) {
static int closePage(lua_State *L) { static int closePage(lua_State *L) {
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
// should be save if called twice // should be safe if called twice
if(page->page_ref != NULL) { if (page->page_ref != NULL) {
ddjvu_page_release(page->page_ref); ddjvu_page_release(page->page_ref);
page->page_ref = NULL; page->page_ref = NULL;
} }
@ -376,74 +423,84 @@ static int drawPage(lua_State *L) {
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage"); DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext"); DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer"); BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer");
ddjvu_render_mode_t djvu_render_mode = (int) luaL_checkint(L, 6);
ddjvu_format_t *pixelformat; unsigned char adjusted_low[16], adjusted_high[16];
int i, adjust_pixels = 0;
ddjvu_rect_t pagerect, renderrect; ddjvu_rect_t pagerect, renderrect;
uint8_t *imagebuffer = NULL; uint8_t *imagebuffer = malloc((bb->w)*(bb->h)+1);
/*printf("@page %d, @@zoom:%f, offset: (%d, %d)\n", page->num, dc->zoom, dc->offset_x, dc->offset_y);*/
imagebuffer = malloc((bb->w)*(bb->h)+1);
/* fill pixel map with white color */ /* fill pixel map with white color */
memset(imagebuffer, 0xFF, (bb->w)*(bb->h)+1); memset(imagebuffer, 0xFF, (bb->w)*(bb->h)+1);
pixelformat = ddjvu_format_create(DDJVU_FORMAT_GREY8, 0, NULL);
ddjvu_format_set_row_order(pixelformat, 1);
ddjvu_format_set_y_direction(pixelformat, 1);
ddjvu_format_set_gamma(pixelformat, dc->gamma);
/*ddjvu_format_set_ditherbits(dc->pixelformat, 2);*/
/* render full page into rectangle specified by pagerect */ /* render full page into rectangle specified by pagerect */
pagerect.x = 0; pagerect.x = 0;
pagerect.y = 0; pagerect.y = 0;
pagerect.w = page->info.width * dc->zoom; pagerect.w = page->info.width * dc->zoom;
pagerect.h = page->info.height * dc->zoom; pagerect.h = page->info.height * dc->zoom;
/*printf("--pagerect--- (x: %d, y: %d), w: %d, h: %d.\n", 0, 0, pagerect.w, pagerect.h);*/
/* copy pixels area from pagerect specified by renderrect. /* copy pixels area from pagerect specified by renderrect.
*
* ddjvulibre library does not support negative offset, positive offset * ddjvulibre library does not support negative offset, positive offset
* means moving towards right and down. * means moving towards right and down.
* *
* However, djvureader.lua handles offset differently. It use negative * However, djvureader.lua handles offset differently. It uses negative
* offset to move right and down while positive offset to move left * offset to move right and down while positive offset to move left
* and up. So we need to handle positive offset manually when copying * and up. So we need to handle positive offset manually when copying
* imagebuffer to blitbuffer (framebuffer). * imagebuffer to blitbuffer (framebuffer).
*/ */
renderrect.x = luaL_checkint(L, 4); renderrect.x = MAX(-dc->offset_x, 0);
renderrect.y = luaL_checkint(L, 5); renderrect.y = MAX(-dc->offset_y, 0);
/*renderrect.x = MAX(-dc->offset_x, 0);*/
/*renderrect.y = MAX(-dc->offset_y, 0);*/
renderrect.w = MIN(pagerect.w - renderrect.x, bb->w); renderrect.w = MIN(pagerect.w - renderrect.x, bb->w);
renderrect.h = MIN(pagerect.h - renderrect.y, bb->h); renderrect.h = MIN(pagerect.h - renderrect.y, bb->h);
/*printf("--renderrect--- (%d, %d), w:%d, h:%d\n", renderrect.x, renderrect.y, renderrect.w, renderrect.h);*/
/* ddjvulibre library only supports rotation of 0, 90, 180 and 270 degrees. /* ddjvulibre library only supports rotation of 0, 90, 180 and 270 degrees.
* This four kinds of rotations can already be achieved by native system. * These four kinds of rotations can already be achieved by native system.
* So we don't set rotation here. * So we don't set rotation here.
*/ */
ddjvu_page_render(page->page_ref, ddjvu_page_render(page->page_ref,
DDJVU_RENDER_COLOR, djvu_render_mode,
&pagerect, &pagerect,
&renderrect, &renderrect,
pixelformat, page->doc->pixelformat,
bb->w, bb->w,
imagebuffer); imagebuffer);
uint8_t *bbptr = (uint8_t*)bb->data; uint8_t *bbptr = bb->data;
uint8_t *pmptr = (uint8_t*)imagebuffer; uint8_t *pmptr = imagebuffer;
int x, y; int x, y;
/* if offset is positive, we are moving towards up and left. */ /* if offset is positive, we are moving towards up and left. */
int x_offset = MAX(0, dc->offset_x); int x_offset = MAX(0, dc->offset_x);
int y_offset = MAX(0, dc->offset_y); int y_offset = MAX(0, dc->offset_y);
/* prepare the tables for adjusting the intensity of pixels */
if (dc->gamma != -1.0) {
for (i=0; i<16; i++) {
adjusted_low[i] = MIN(15, (unsigned char)floorf(dc->gamma * (float)i));
adjusted_high[i] = adjusted_low[i] << 4;
}
adjust_pixels = 1;
}
bbptr += bb->pitch * y_offset; bbptr += bb->pitch * y_offset;
for(y = y_offset; y < bb->h; y++) { for(y = y_offset; y < bb->h; y++) {
/* bbptr's line width is half of pmptr's */ /* bbptr's line width is half of pmptr's */
for(x = x_offset/2; x < (bb->w / 2); x++) { for(x = x_offset/2; x < (bb->w / 2); x++) {
bbptr[x] = 255 - (((pmptr[x*2 + 1 - x_offset] & 0xF0) >> 4) | int p = x*2 - x_offset;
(pmptr[x*2 - x_offset] & 0xF0)); unsigned char low = 15 - (pmptr[p + 1] >> 4);
unsigned char high = 15 - (pmptr[p] >> 4);
if (adjust_pixels)
bbptr[x] = adjusted_high[high] | adjusted_low[low];
else
bbptr[x] = (high << 4) | low;
} }
if(bb->w & 1) { if (bb->w & 1) {
bbptr[x] = 255 - (pmptr[x*2] & 0xF0); bbptr[x] = 255 - (pmptr[x*2] & 0xF0);
} }
/* go to next line */ /* go to next line */
@ -452,9 +509,6 @@ static int drawPage(lua_State *L) {
} }
free(imagebuffer); free(imagebuffer);
pmptr = imagebuffer = NULL;
ddjvu_format_release(pixelformat);
return 0; return 0;
} }
@ -483,6 +537,7 @@ static const struct luaL_Reg djvudocument_meth[] = {
{"getPages", getNumberOfPages}, {"getPages", getNumberOfPages},
{"getToc", getTableOfContent}, {"getToc", getTableOfContent},
{"getPageText", getPageText}, {"getPageText", getPageText},
{"getOriginalPageSize", getOriginalPageSize},
{"close", closeDocument}, {"close", closeDocument},
{"getCacheSize", getCacheSize}, {"getCacheSize", getCacheSize},
{"cleanCache", cleanCache}, {"cleanCache", cleanCache},

View File

@ -25,6 +25,9 @@ end
function CreDocument:engineInit() function CreDocument:engineInit()
if not engine_initilized then if not engine_initilized then
-- initialize cache
cre.initCache(1024*1024*64)
-- we need to initialize the CRE font list -- we need to initialize the CRE font list
local fonts = Font:getFontList() local fonts = Font:getFontList()
for _k, _v in ipairs(fonts) do for _k, _v in ipairs(fonts) do

View File

@ -11,7 +11,7 @@ end
function DocumentRegistry:getProvider(file) function DocumentRegistry:getProvider(file)
-- TODO: some implementation based on mime types? -- TODO: some implementation based on mime types?
local extension = string.lower(string.match(file, ".+%.([^.]+)")) local extension = string.lower(string.match(file, ".+%.([^.]+)") or "")
for _, provider in ipairs(self.providers) do for _, provider in ipairs(self.providers) do
if extension == provider.extension then if extension == provider.extension then
return provider.provider return provider.provider

View File

@ -8,7 +8,7 @@ ReaderToc = InputContainer:new{
} }
function ReaderToc:cleanUpTocTitle(title) function ReaderToc:cleanUpTocTitle(title)
return title:gsub("\13", "") return (title:gsub("\13", ""))
end end
function ReaderToc:onSetDimensions(dimen) function ReaderToc:onSetDimensions(dimen)

View File

@ -9,14 +9,14 @@ SET(CR_3RDPARTY_DIR crengine/thirdparty)
SET(CR3_PNG 1) SET(CR3_PNG 1)
#SET(CR3_JPEG 1) #SET(CR3_JPEG 1)
SET(FREETYPE_INCLUDE_DIRS ${MUPDF_3RDPARTY_DIR}/freetype-2.4.9/include) SET(FREETYPE_INCLUDE_DIRS ${MUPDF_3RDPARTY_DIR}/freetype-2.4.10/include)
#SET(FREETYPE_INCLUDE_DIRS ${CR_3RDPARTY_DIR}/freetype/include) #SET(FREETYPE_INCLUDE_DIRS ${CR_3RDPARTY_DIR}/freetype/include)
SET(ANTIWORD_INCLUDE_DIR ${CR_3RDPARTY_DIR}/antiword) SET(ANTIWORD_INCLUDE_DIR ${CR_3RDPARTY_DIR}/antiword)
SET(CHM_INCLUDE_DIRS ${CR_3RDPARTY_DIR}/chmlib) SET(CHM_INCLUDE_DIRS ${CR_3RDPARTY_DIR}/chmlib)
SET(PNG_INCLUDE_DIR ${CR_3RDPARTY_DIR}/libpng) SET(PNG_INCLUDE_DIR ${CR_3RDPARTY_DIR}/libpng)
SET(ZLIB_INCLUDE_DIR ${MUPDF_3RDPARTY_DIR}/zlib-1.2.5) SET(ZLIB_INCLUDE_DIR ${MUPDF_3RDPARTY_DIR}/zlib-1.2.7)
#SET(ZLIB_INCLUDE_DIR ${CR_3RDPARTY_DIR}/zlib) #SET(ZLIB_INCLUDE_DIR ${CR_3RDPARTY_DIR}/zlib)
SET(JPEGLIB_INCLUDE_DIR ${MUPDF_3RDPARTY_DIR}/jpeg-8d) SET(JPEGLIB_INCLUDE_DIR ${MUPDF_3RDPARTY_DIR}/jpeg-9)
#SET(JPEGLIB_INCLUDE_DIR ${CR_3RDPARTY_DIR}/libjpeg) #SET(JPEGLIB_INCLUDE_DIR ${CR_3RDPARTY_DIR}/libjpeg)
SET(JCONFIG_INCLUDE_DIR ${MUPDF_DIR}/scripts) SET(JCONFIG_INCLUDE_DIR ${MUPDF_DIR}/scripts)

2
util.h
View File

@ -1,5 +1,5 @@
/* /*
KindlePDFViewer: buffer for blitting muPDF data to framebuffer (blitbuffer) KindlePDFViewer: miscellaneous utility functions for Lua
Copyright (C) 2011 Hans-Werner Hilse <hilse@web.de> Copyright (C) 2011 Hans-Werner Hilse <hilse@web.de>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify