From 7b120b0ee026790f4b73548fa5b1c9119e04b896 Mon Sep 17 00:00:00 2001 From: HW Date: Sun, 18 Mar 2012 11:48:26 +0100 Subject: [PATCH 01/12] allow easier customization of toolchain for libdjvu --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7a1e19509..1556b31b0 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ LFSDIR=luafilesystem CC:=arm-unknown-linux-gnueabi-gcc CXX:=arm-unknown-linux-gnueabi-g++ +HOST:=arm-unknown-linux-gnueabi ifdef SBOX_UNAME_MACHINE CC:=gcc CXX:=g++ @@ -133,7 +134,7 @@ $(DJVULIBS): ifdef EMULATE_READER cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static else - cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static --host=arm-kindle-linux-gnueabi + cd $(DJVUDIR)/build && ../configure --disable-desktopfiles --disable-shared --enable-static --host=$(HOST) endif make -C $(DJVUDIR)/build From 929ea1e703d7f6636837a59c141eba91d506a13e Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 18:24:43 +0100 Subject: [PATCH 02/12] removed obsolete page rotation handling, closes #70 --- pdf.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/pdf.c b/pdf.c index 1091ecc6a..038a354aa 100644 --- a/pdf.c +++ b/pdf.c @@ -240,15 +240,15 @@ static int openPage(lua_State *L) { static int getPageSize(lua_State *L) { fz_matrix ctm; + fz_rect bounds; fz_rect bbox; PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage"); DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext"); - ctm = fz_translate(0, -page->page->mediabox.y1); - ctm = fz_concat(ctm, fz_scale(dc->zoom, -dc->zoom)); - ctm = fz_concat(ctm, fz_rotate(page->page->rotate)); + bounds = fz_bound_page(page->doc->xref, page->page); + ctm = fz_scale(dc->zoom, dc->zoom) ; ctm = fz_concat(ctm, fz_rotate(dc->rotate)); - bbox = fz_transform_rect(ctm, page->page->mediabox); + bbox = fz_transform_rect(ctm, bounds); lua_pushnumber(L, bbox.x1-bbox.x0); lua_pushnumber(L, bbox.y1-bbox.y0); @@ -264,7 +264,6 @@ static int getUsedBBox(lua_State *L) { /* returned BBox is in centi-point (n * 0.01 pt) */ ctm = fz_scale(100, 100); - ctm = fz_concat(ctm, fz_rotate(page->page->rotate)); fz_try(page->doc->context) { dev = fz_new_bbox_device(page->doc->context, &result); @@ -312,7 +311,6 @@ static int drawPage(lua_State *L) { fz_clear_pixmap_with_value(page->doc->context, pix, 0xff); ctm = fz_scale(dc->zoom, dc->zoom); - ctm = fz_concat(ctm, fz_rotate(page->page->rotate)); ctm = fz_concat(ctm, fz_rotate(dc->rotate)); ctm = fz_concat(ctm, fz_translate(dc->offset_x, dc->offset_y)); dev = fz_new_draw_device(page->doc->context, pix); From 9ee7afa86d6e18ad67c2203f21c8a69847ad35d8 Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 18:59:36 +0100 Subject: [PATCH 03/12] separate DC out of pdf.c and djvu.c (cleanup) --- djvu.c | 100 +----------------------------------------- djvureader.lua | 11 +---- drawcontext.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++ drawcontext.h | 35 +++++++++++++++ kpdfview.c | 2 + pdf.c | 98 +---------------------------------------- pdfreader.lua | 11 +---- unireader.lua | 8 +--- 8 files changed, 160 insertions(+), 222 deletions(-) create mode 100644 drawcontext.c create mode 100644 drawcontext.h diff --git a/djvu.c b/djvu.c index d2b804662..76617399a 100644 --- a/djvu.c +++ b/djvu.c @@ -20,6 +20,7 @@ #include "string.h" #include "blitbuffer.h" +#include "drawcontext.h" #include "djvu.h" #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -40,14 +41,6 @@ typedef struct DjvuPage { DjvuDocument *doc; } DjvuPage; -typedef struct DrawContext { - int rotate; - double zoom; - double gamma; - int offset_x; - int offset_y; -} DrawContext; - static int handle(lua_State *L, ddjvu_context_t *ctx, int wait) { @@ -177,77 +170,6 @@ static int getTableOfContent(lua_State *L) { return 1; } -static int newDrawContext(lua_State *L) { - int rotate = luaL_optint(L, 1, 0); - double zoom = luaL_optnumber(L, 2, (double) 1.0); - int offset_x = luaL_optint(L, 3, 0); - int offset_y = luaL_optint(L, 4, 0); - double gamma = luaL_optnumber(L, 5, (double) -1.0); - - DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext)); - dc->rotate = rotate; - dc->zoom = zoom; - dc->offset_x = offset_x; - dc->offset_y = offset_y; - dc->gamma = gamma; - - - luaL_getmetatable(L, "drawcontext"); - lua_setmetatable(L, -2); - - return 1; -} - -static int dcSetOffset(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->offset_x = luaL_checkint(L, 2); - dc->offset_y = luaL_checkint(L, 3); - return 0; -} - -static int dcGetOffset(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushinteger(L, dc->offset_x); - lua_pushinteger(L, dc->offset_y); - return 2; -} - -static int dcSetRotate(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->rotate = luaL_checkint(L, 2); - return 0; -} - -static int dcSetZoom(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->zoom = luaL_checknumber(L, 2); - return 0; -} - -static int dcGetRotate(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushinteger(L, dc->rotate); - return 1; -} - -static int dcGetZoom(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushnumber(L, dc->zoom); - return 1; -} - -static int dcSetGamma(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->gamma = luaL_checknumber(L, 2); - return 0; -} - -static int dcGetGamma(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushnumber(L, dc->gamma); - return 1; -} - static int openPage(lua_State *L) { ddjvu_status_t r; DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); @@ -407,7 +329,6 @@ static int drawPage(lua_State *L) { static const struct luaL_reg djvu_func[] = { {"openDocument", openDocument}, - {"newDC", newDrawContext}, {NULL, NULL} }; @@ -429,18 +350,6 @@ static const struct luaL_reg djvupage_meth[] = { {NULL, NULL} }; -static const struct luaL_reg drawcontext_meth[] = { - {"setRotate", dcSetRotate}, - {"getRotate", dcGetRotate}, - {"setZoom", dcSetZoom}, - {"getZoom", dcGetZoom}, - {"setOffset", dcSetOffset}, - {"getOffset", dcGetOffset}, - {"setGamma", dcSetGamma}, - {"getGamma", dcGetGamma}, - {NULL, NULL} -}; - int luaopen_djvu(lua_State *L) { luaL_newmetatable(L, "djvudocument"); lua_pushstring(L, "__index"); @@ -456,13 +365,6 @@ int luaopen_djvu(lua_State *L) { luaL_register(L, NULL, djvupage_meth); lua_pop(L, 1); - luaL_newmetatable(L, "drawcontext"); - lua_pushstring(L, "__index"); - lua_pushvalue(L, -2); - lua_settable(L, -3); - luaL_register(L, NULL, drawcontext_meth); - lua_pop(L, 1); - luaL_register(L, "djvu", djvu_func); return 1; } diff --git a/djvureader.lua b/djvureader.lua index e929f765d..1b4b37697 100644 --- a/djvureader.lua +++ b/djvureader.lua @@ -1,15 +1,6 @@ require "unireader" -DJVUReader = UniReader:new{ - newDC = function() - print("djvu.newDC") - return djvu.newDC() - end, -} - -function DJVUReader:init() - self.nulldc = self.newDC() -end +DJVUReader = UniReader:new{} -- open a DJVU file and its settings store -- DJVU does not support password yet diff --git a/drawcontext.c b/drawcontext.c new file mode 100644 index 000000000..1dacb1298 --- /dev/null +++ b/drawcontext.c @@ -0,0 +1,117 @@ +/* + KindlePDFViewer: a DC abstraction + Copyright (C) 2012 Hans-Werner Hilse + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "drawcontext.h" + +static int newDrawContext(lua_State *L) { + int rotate = luaL_optint(L, 1, 0); + double zoom = luaL_optnumber(L, 2, (double) 1.0); + int offset_x = luaL_optint(L, 3, 0); + int offset_y = luaL_optint(L, 4, 0); + double gamma = luaL_optnumber(L, 5, (double) -1.0); + + DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext)); + dc->rotate = rotate; + dc->zoom = zoom; + dc->offset_x = offset_x; + dc->offset_y = offset_y; + dc->gamma = gamma; + + luaL_getmetatable(L, "drawcontext"); + lua_setmetatable(L, -2); + + return 1; +} + +static int dcSetOffset(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + dc->offset_x = luaL_checkint(L, 2); + dc->offset_y = luaL_checkint(L, 3); + return 0; +} + +static int dcGetOffset(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + lua_pushinteger(L, dc->offset_x); + lua_pushinteger(L, dc->offset_y); + return 2; +} + +static int dcSetRotate(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + dc->rotate = luaL_checkint(L, 2); + return 0; +} + +static int dcSetZoom(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + dc->zoom = luaL_checknumber(L, 2); + return 0; +} + +static int dcGetRotate(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + lua_pushinteger(L, dc->rotate); + return 1; +} + +static int dcGetZoom(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + lua_pushnumber(L, dc->zoom); + return 1; +} + +static int dcSetGamma(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + dc->gamma = luaL_checknumber(L, 2); + return 0; +} + +static int dcGetGamma(lua_State *L) { + DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); + lua_pushnumber(L, dc->gamma); + return 1; +} + +static const struct luaL_reg drawcontext_meth[] = { + {"setRotate", dcSetRotate}, + {"getRotate", dcGetRotate}, + {"setZoom", dcSetZoom}, + {"getZoom", dcGetZoom}, + {"setOffset", dcSetOffset}, + {"getOffset", dcGetOffset}, + {"setGamma", dcSetGamma}, + {"getGamma", dcGetGamma}, + {NULL, NULL} +}; + +static const struct luaL_reg drawcontext_func[] = { + {"new", newDrawContext}, + {NULL, NULL} +}; + +int luaopen_drawcontext(lua_State *L) { + luaL_newmetatable(L, "drawcontext"); + lua_pushstring(L, "__index"); + lua_pushvalue(L, -2); + lua_settable(L, -3); + luaL_register(L, NULL, drawcontext_meth); + lua_pop(L, 1); + luaL_register(L, "DrawContext", drawcontext_func); + return 1; +} diff --git a/drawcontext.h b/drawcontext.h new file mode 100644 index 000000000..c8440afb5 --- /dev/null +++ b/drawcontext.h @@ -0,0 +1,35 @@ +/* + KindlePDFViewer: a DC abstraction + Copyright (C) 2012 Hans-Werner Hilse + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +#ifndef _DRAWCONTEXT_H +#define _DRAWCONTEXT_H + +#include +#include +#include + +typedef struct DrawContext { + int rotate; + double zoom; + double gamma; + int offset_x; + int offset_y; +} DrawContext; + +int luaopen_drawcontext(lua_State *L); +#endif + diff --git a/kpdfview.c b/kpdfview.c index 9ce45652c..d14a38053 100644 --- a/kpdfview.c +++ b/kpdfview.c @@ -24,6 +24,7 @@ #include #include "blitbuffer.h" +#include "drawcontext.h" #include "pdf.h" #include "einkfb.h" #include "input.h" @@ -48,6 +49,7 @@ int main(int argc, char **argv) { luaL_openlibs(L); luaopen_blitbuffer(L); + luaopen_drawcontext(L); luaopen_einkfb(L); luaopen_pdf(L); luaopen_djvu(L); diff --git a/pdf.c b/pdf.c index 038a354aa..5644300fc 100644 --- a/pdf.c +++ b/pdf.c @@ -19,6 +19,7 @@ #include #include "blitbuffer.h" +#include "drawcontext.h" #include "pdf.h" typedef struct PdfDocument { @@ -36,14 +37,6 @@ typedef struct PdfPage { PdfDocument *doc; } PdfPage; -typedef struct DrawContext { - int rotate; - double zoom; - double gamma; - int offset_x; - int offset_y; -} DrawContext; - static int openDocument(lua_State *L) { const char *filename = luaL_checkstring(L, 1); const char *password = luaL_checkstring(L, 2); @@ -140,76 +133,6 @@ static int getTableOfContent(lua_State *L) { return 1; } -static int newDrawContext(lua_State *L) { - int rotate = luaL_optint(L, 1, 0); - double zoom = luaL_optnumber(L, 2, (double) 1.0); - int offset_x = luaL_optint(L, 3, 0); - int offset_y = luaL_optint(L, 4, 0); - double gamma = luaL_optnumber(L, 5, (double) -1.0); - - DrawContext *dc = (DrawContext*) lua_newuserdata(L, sizeof(DrawContext)); - dc->rotate = rotate; - dc->zoom = zoom; - dc->offset_x = offset_x; - dc->offset_y = offset_y; - dc->gamma = gamma; - - luaL_getmetatable(L, "drawcontext"); - lua_setmetatable(L, -2); - - return 1; -} - -static int dcSetOffset(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->offset_x = luaL_checkint(L, 2); - dc->offset_y = luaL_checkint(L, 3); - return 0; -} - -static int dcGetOffset(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushinteger(L, dc->offset_x); - lua_pushinteger(L, dc->offset_y); - return 2; -} - -static int dcSetRotate(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->rotate = luaL_checkint(L, 2); - return 0; -} - -static int dcSetZoom(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->zoom = luaL_checknumber(L, 2); - return 0; -} - -static int dcGetRotate(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushinteger(L, dc->rotate); - return 1; -} - -static int dcGetZoom(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushnumber(L, dc->zoom); - return 1; -} - -static int dcSetGamma(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - dc->gamma = luaL_checknumber(L, 2); - return 0; -} - -static int dcGetGamma(lua_State *L) { - DrawContext *dc = (DrawContext*) luaL_checkudata(L, 1, "drawcontext"); - lua_pushnumber(L, dc->gamma); - return 1; -} - static int openPage(lua_State *L) { fz_device *dev; @@ -353,7 +276,6 @@ static int drawPage(lua_State *L) { static const struct luaL_reg pdf_func[] = { {"openDocument", openDocument}, - {"newDC", newDrawContext}, {NULL, NULL} }; @@ -375,18 +297,6 @@ static const struct luaL_reg pdfpage_meth[] = { {NULL, NULL} }; -static const struct luaL_reg drawcontext_meth[] = { - {"setRotate", dcSetRotate}, - {"getRotate", dcGetRotate}, - {"setZoom", dcSetZoom}, - {"getZoom", dcGetZoom}, - {"setOffset", dcSetOffset}, - {"getOffset", dcGetOffset}, - {"setGamma", dcSetGamma}, - {"getGamma", dcGetGamma}, - {NULL, NULL} -}; - int luaopen_pdf(lua_State *L) { luaL_newmetatable(L, "pdfdocument"); lua_pushstring(L, "__index"); @@ -400,12 +310,6 @@ int luaopen_pdf(lua_State *L) { lua_settable(L, -3); luaL_register(L, NULL, pdfpage_meth); lua_pop(L, 1); - luaL_newmetatable(L, "drawcontext"); - lua_pushstring(L, "__index"); - lua_pushvalue(L, -2); - lua_settable(L, -3); - luaL_register(L, NULL, drawcontext_meth); - lua_pop(L, 1); luaL_register(L, "pdf", pdf_func); return 1; } diff --git a/pdfreader.lua b/pdfreader.lua index 5bd12aa73..2af16f1cb 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,15 +1,6 @@ require "unireader" -PDFReader = UniReader:new{ - newDC = function() - print("pdf.newDC") - return pdf.newDC() - end, -} - -function PDFReader:init() - self.nulldc = self.newDC(); -end +PDFReader = UniReader:new{} -- open a PDF file and its settings store function PDFReader:open(filename, password) diff --git a/unireader.lua b/unireader.lua index c81262b89..27251a486 100644 --- a/unireader.lua +++ b/unireader.lua @@ -55,10 +55,8 @@ UniReader = { -- the document's setting store: settings = nil, - -- you have to initialize newDC, nulldc in specific reader - newDC = function() return nil end, -- we will use this one often, so keep it "static": - nulldc = nil, + nulldc = DrawContext.new(), -- tile cache configuration: cache_max_memsize = 1024*1024*5, -- 5MB tile cache @@ -87,13 +85,11 @@ end For a new specific reader, you must always overwrite following two methods: - * self:init() * self:open() overwrite other methods if needed. --]] function UniReader:init() - print("empty initialization method!") end -- open a file and its settings store @@ -286,7 +282,7 @@ end -- set viewer state according to zoom state function UniReader:setzoom(page) - local dc = self.newDC() + local dc = DrawContext.new() local pwidth, pheight = page:getSize(self.nulldc) print("# page::getSize "..pwidth.."*"..pheight); local x0, y0, x1, y1 = page:getUsedBBox() From 8869c52c31331e3b38125f3d72fb760d03c2c212 Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 19:11:32 +0100 Subject: [PATCH 04/12] fix a Lua 5.0 syntax that was deprecated in 5.1 luaL_reg is now renamed to luaL_Reg. Lua 5.2 does not know about the old name anymore, Lua 5.1.x had backward compatibility. --- blitbuffer.c | 4 ++-- djvu.c | 6 +++--- drawcontext.c | 4 ++-- einkfb.c | 4 ++-- ft.c | 4 ++-- input.c | 2 +- pdf.c | 6 +++--- util.c | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/blitbuffer.c b/blitbuffer.c index c8a51de7f..93642fd61 100644 --- a/blitbuffer.c +++ b/blitbuffer.c @@ -366,12 +366,12 @@ static int paintRect(lua_State *L) { return 0; } -static const struct luaL_reg blitbuffer_func[] = { +static const struct luaL_Reg blitbuffer_func[] = { {"new", newBlitBuffer}, {NULL, NULL} }; -static const struct luaL_reg blitbuffer_meth[] = { +static const struct luaL_Reg blitbuffer_meth[] = { {"getWidth", getWidth}, {"getHeight", getHeight}, {"blitFrom", blitToBuffer}, diff --git a/djvu.c b/djvu.c index 76617399a..43ed4d28c 100644 --- a/djvu.c +++ b/djvu.c @@ -327,12 +327,12 @@ static int drawPage(lua_State *L) { return 0; } -static const struct luaL_reg djvu_func[] = { +static const struct luaL_Reg djvu_func[] = { {"openDocument", openDocument}, {NULL, NULL} }; -static const struct luaL_reg djvudocument_meth[] = { +static const struct luaL_Reg djvudocument_meth[] = { {"openPage", openPage}, {"getPages", getNumberOfPages}, {"getTOC", getTableOfContent}, @@ -341,7 +341,7 @@ static const struct luaL_reg djvudocument_meth[] = { {NULL, NULL} }; -static const struct luaL_reg djvupage_meth[] = { +static const struct luaL_Reg djvupage_meth[] = { {"getSize", getPageSize}, {"getUsedBBox", getUsedBBox}, {"close", closePage}, diff --git a/drawcontext.c b/drawcontext.c index 1dacb1298..9a4ac5d5f 100644 --- a/drawcontext.c +++ b/drawcontext.c @@ -88,7 +88,7 @@ static int dcGetGamma(lua_State *L) { return 1; } -static const struct luaL_reg drawcontext_meth[] = { +static const struct luaL_Reg drawcontext_meth[] = { {"setRotate", dcSetRotate}, {"getRotate", dcGetRotate}, {"setZoom", dcSetZoom}, @@ -100,7 +100,7 @@ static const struct luaL_reg drawcontext_meth[] = { {NULL, NULL} }; -static const struct luaL_reg drawcontext_func[] = { +static const struct luaL_Reg drawcontext_func[] = { {"new", newDrawContext}, {NULL, NULL} }; diff --git a/einkfb.c b/einkfb.c index 4abb81b23..a1f7054f9 100644 --- a/einkfb.c +++ b/einkfb.c @@ -203,12 +203,12 @@ static int einkSetOrientation(lua_State *L) { } -static const struct luaL_reg einkfb_func[] = { +static const struct luaL_Reg einkfb_func[] = { {"open", openFrameBuffer}, {NULL, NULL} }; -static const struct luaL_reg einkfb_meth[] = { +static const struct luaL_Reg einkfb_meth[] = { {"close", closeFrameBuffer}, {"__gc", closeFrameBuffer}, {"refresh", einkUpdate}, diff --git a/ft.c b/ft.c index 5cfc9b69b..151ba4c48 100644 --- a/ft.c +++ b/ft.c @@ -181,7 +181,7 @@ static int doneFace(lua_State *L) { return 0; } -static const struct luaL_reg ft_face_meth[] = { +static const struct luaL_Reg ft_face_meth[] = { {"renderGlyph", renderGlyph}, {"hasKerning", hasKerning}, {"getKerning", getKerning}, @@ -190,7 +190,7 @@ static const struct luaL_reg ft_face_meth[] = { {NULL, NULL} }; -static const struct luaL_reg ft_func[] = { +static const struct luaL_Reg ft_func[] = { {"newFace", newFace}, {"newBuiltinFace", newBuiltinFace}, {NULL, NULL} diff --git a/input.c b/input.c index bca89fc4b..05eedaa49 100644 --- a/input.c +++ b/input.c @@ -144,7 +144,7 @@ static int waitForInput(lua_State *L) { #endif } -static const struct luaL_reg input_func[] = { +static const struct luaL_Reg input_func[] = { {"open", openInputDevice}, {"closeAll", closeInputDevices}, {"waitForEvent", waitForInput}, diff --git a/pdf.c b/pdf.c index 5644300fc..33c8b0720 100644 --- a/pdf.c +++ b/pdf.c @@ -274,12 +274,12 @@ static int drawPage(lua_State *L) { return 0; } -static const struct luaL_reg pdf_func[] = { +static const struct luaL_Reg pdf_func[] = { {"openDocument", openDocument}, {NULL, NULL} }; -static const struct luaL_reg pdfdocument_meth[] = { +static const struct luaL_Reg pdfdocument_meth[] = { {"openPage", openPage}, {"getPages", getNumberOfPages}, {"getTOC", getTableOfContent}, @@ -288,7 +288,7 @@ static const struct luaL_reg pdfdocument_meth[] = { {NULL, NULL} }; -static const struct luaL_reg pdfpage_meth[] = { +static const struct luaL_Reg pdfpage_meth[] = { {"getSize", getPageSize}, {"getUsedBBox", getUsedBBox}, {"close", closePage}, diff --git a/util.c b/util.c index 7da912fc0..571792bf4 100644 --- a/util.c +++ b/util.c @@ -46,7 +46,7 @@ static int utf8charcode(lua_State *L) { return 1; } -static const struct luaL_reg util_func[] = { +static const struct luaL_Reg util_func[] = { {"gettime", gettime}, {"utf8charcode", utf8charcode}, {NULL, NULL} From a49c8fa2e5df325ddc9f752da65905b2e9912d28 Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 22:04:49 +0100 Subject: [PATCH 05/12] forgot Makefile change when factoring out drawcontext --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1556b31b0..ce64f0778 100644 --- a/Makefile +++ b/Makefile @@ -63,12 +63,13 @@ THIRDPARTYLIBS := $(MUPDFLIBDIR)/libfreetype.a \ LUALIB := $(LUADIR)/src/liblua.a -kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o input.o util.o ft.o lfs.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) djvu.o +kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o drawcontext.o input.o util.o ft.o lfs.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) djvu.o $(CC) -lm -ldl -lpthread $(EMU_LDFLAGS) -lstdc++ \ kpdfview.o \ einkfb.o \ pdf.o \ blitbuffer.o \ + drawcontext.o \ input.o \ util.o \ ft.o \ @@ -86,7 +87,7 @@ einkfb.o input.o: %.o: %.c ft.o: %.o: %.c $(CC) -c $(KPDFREADER_CFLAGS) -I$(FREETYPEDIR)/include $< -o $@ -kpdfview.o pdf.o blitbuffer.o util.o: %.o: %.c +kpdfview.o pdf.o blitbuffer.o util.o drawcontext.o: %.o: %.c $(CC) -c $(KPDFREADER_CFLAGS) -I$(LFSDIR)/src $< -o $@ djvu.o: %.o: %.c From ee51fe7e6d9a3bcf1f86ec7496facca9357ba51c Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 22:24:24 +0100 Subject: [PATCH 06/12] refactored muPDF integration to use strictly the fitz.h API This will allow for reading XPS and CBZ documents, since those are supported by muPDF (not tested yet) --- pdf.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/pdf.c b/pdf.c index 33c8b0720..16ab2b942 100644 --- a/pdf.c +++ b/pdf.c @@ -16,14 +16,13 @@ along with this program. If not, see . */ #include -#include #include "blitbuffer.h" #include "drawcontext.h" #include "pdf.h" typedef struct PdfDocument { - pdf_document *xref; + fz_document *xref; fz_context *context; int pages; } PdfDocument; @@ -33,13 +32,13 @@ typedef struct PdfPage { #ifdef USE_DISPLAY_LIST fz_display_list *list; #endif - pdf_page *page; + fz_page *page; PdfDocument *doc; } PdfPage; static int openDocument(lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *password = luaL_checkstring(L, 2); + char *filename = strdup(luaL_checkstring(L, 1)); + char *password = strdup(luaL_checkstring(L, 2)); PdfDocument *doc = (PdfDocument*) lua_newuserdata(L, sizeof(PdfDocument)); luaL_getmetatable(L, "pdfdocument"); @@ -48,24 +47,31 @@ static int openDocument(lua_State *L) { doc->context = fz_new_context(NULL, NULL, 64 << 20); // 64MB limit fz_try(doc->context) { - doc->xref = pdf_open_document(doc->context, filename); + doc->xref = fz_open_document(doc->context, filename); } fz_catch(doc->context) { + free(filename); + free(password); return luaL_error(L, "cannot open PDF file <%s>", filename); } - if(pdf_needs_password(doc->xref)) { - if (!pdf_authenticate_password(doc->xref, password)) + if(fz_needs_password(doc->xref)) { + if (!fz_authenticate_password(doc->xref, password)) { + free(filename); + free(password); return luaL_error(L, "cannot authenticate"); + } } - doc->pages = pdf_count_pages(doc->xref); + doc->pages = fz_count_pages(doc->xref); + free(filename); + free(password); return 1; } static int closeDocument(lua_State *L) { PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); if(doc->xref != NULL) { - pdf_close_document(doc->xref); + fz_close_document(doc->xref); doc->xref = NULL; } if(doc->context != NULL) { @@ -126,7 +132,7 @@ static int getTableOfContent(lua_State *L) { int count = 1; PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); - ol = pdf_load_outline(doc->xref); + ol = fz_load_outline(doc->xref); lua_newtable(L); walkTableOfContent(L, ol, &count, 0); @@ -150,7 +156,7 @@ static int openPage(lua_State *L) { lua_setmetatable(L, -2); fz_try(doc->context) { - page->page = pdf_load_page(doc->xref, pageno - 1); + page->page = fz_load_page(doc->xref, pageno - 1); } fz_catch(doc->context) { return luaL_error(L, "cannot open page #%d", pageno); @@ -190,7 +196,7 @@ static int getUsedBBox(lua_State *L) { fz_try(page->doc->context) { dev = fz_new_bbox_device(page->doc->context, &result); - pdf_run_page(page->doc->xref, page->page, dev, ctm, NULL); + fz_run_page(page->doc->xref, page->page, dev, ctm, NULL); } fz_always(page->doc->context) { fz_free_device(dev); @@ -210,7 +216,7 @@ static int getUsedBBox(lua_State *L) { static int closePage(lua_State *L) { PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage"); if(page->page != NULL) { - pdf_free_page(page->doc->xref, page->page); + fz_free_page(page->doc->xref, page->page); page->page = NULL; } return 0; @@ -241,13 +247,13 @@ static int drawPage(lua_State *L) { fz_device *tdev; fz_try(page->doc->context) { tdev = fz_new_trace_device(page->doc->context); - pdf_run_page(page->doc->xref, page->page, tdev, ctm, NULL); + fz_run_page(page->doc->xref, page->page, tdev, ctm, NULL); } fz_always(page->doc->context) { fz_free_device(tdev); } #endif - pdf_run_page(page->doc->xref, page->page, dev, ctm, NULL); + fz_run_page(page->doc->xref, page->page, dev, ctm, NULL); fz_free_device(dev); if(dc->gamma >= 0.0) { From 2fcfe4a32957e588e4e0b8147bd18190a60cffef Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 22:29:06 +0100 Subject: [PATCH 07/12] fixed bug for odd rendering widths --- pdf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdf.c b/pdf.c index 16ab2b942..e57bcf76d 100644 --- a/pdf.c +++ b/pdf.c @@ -269,7 +269,7 @@ static int drawPage(lua_State *L) { bbptr[x] = (((pmptr[x*2 + 1] & 0xF0) >> 4) | (pmptr[x*2] & 0xF0)) ^ 0xFF; } if(bb->w & 1) { - bbptr[x] = pmptr[x*2] & 0xF0; + bbptr[x] = (pmptr[x*2] & 0xF0) ^ 0xF0; } bbptr += bb->pitch; pmptr += bb->w; From 48463d4739cf5ffc27b3a4eb287061a0c114910e Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 22:35:16 +0100 Subject: [PATCH 08/12] add XPS and CBZ support (muPDF provides this) --- filechooser.lua | 7 +++++-- reader.lua | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/filechooser.lua b/filechooser.lua index ae24642c2..9e909198d 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -52,8 +52,11 @@ function FileChooser:readdir() if lfs.attributes(self.path.."/"..f, "mode") == "directory" and f ~= "." and not (f==".." and self.path=="/") and not string.match(f, "^%.[^.]") then --print(self.path.." -> adding: '"..f.."'") table.insert(self.dirs, f) - elseif string.match(f, ".+%.[pP][dD][fF]$") or string.match(f, ".+%.[dD][jJ][vV][uU]$") then - table.insert(self.files, f) + else + local file_type = string.lower(string.match(f, ".+%.([^.]+)") or "") + if file_type == "djvu" or file_type == "pdf" or file_type == "xps" or file_type == "cbz" then + table.insert(self.files, f) + end end end --@TODO make sure .. is sortted to the first item 16.02 2012 diff --git a/reader.lua b/reader.lua index 9c18d3cee..83cc0bb1d 100755 --- a/reader.lua +++ b/reader.lua @@ -34,7 +34,7 @@ longopts = { } function openFile(filename) - local file_type = string.lower(string.match(filename, ".+%.(.+)")) + local file_type = string.lower(string.match(filename, ".+%.([^.]+)")) if file_type == "djvu" then if DJVUReader:open(filename) then page_num = DJVUReader.settings:readsetting("last_page") or 1 @@ -42,7 +42,7 @@ function openFile(filename) reader_settings:savesetting("lastfile", filename) return DJVUReader:inputloop() end - elseif file_type == "pdf" then + elseif file_type == "pdf" or file_type == "xps" or file_type == "cbz" then if PDFReader:open(filename,"") then -- TODO: query for password page_num = PDFReader.settings:readsetting("last_page") or 1 PDFReader:goto(tonumber(page_num)) From 14b26a4aebd5c95aab5d7b245e9055b2abd4c9ff Mon Sep 17 00:00:00 2001 From: HW Date: Mon, 19 Mar 2012 22:48:54 +0100 Subject: [PATCH 09/12] make muPDF cache size configurable from Lua --- pdf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pdf.c b/pdf.c index e57bcf76d..9f4935420 100644 --- a/pdf.c +++ b/pdf.c @@ -39,12 +39,14 @@ typedef struct PdfPage { static int openDocument(lua_State *L) { char *filename = strdup(luaL_checkstring(L, 1)); char *password = strdup(luaL_checkstring(L, 2)); + int cachesize = luaL_optint(L, 3, 64 << 20); // 64 MB limit default + PdfDocument *doc = (PdfDocument*) lua_newuserdata(L, sizeof(PdfDocument)); luaL_getmetatable(L, "pdfdocument"); lua_setmetatable(L, -2); - doc->context = fz_new_context(NULL, NULL, 64 << 20); // 64MB limit + doc->context = fz_new_context(NULL, NULL, cachesize); fz_try(doc->context) { doc->xref = fz_open_document(doc->context, filename); From 87ec4bbf6b8276c2cc5399291a70234156a8157e Mon Sep 17 00:00:00 2001 From: HW Date: Tue, 20 Mar 2012 00:03:09 +0100 Subject: [PATCH 10/12] factored pages counter out of document struct --- djvu.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/djvu.c b/djvu.c index 43ed4d28c..090d625a3 100644 --- a/djvu.c +++ b/djvu.c @@ -31,7 +31,6 @@ typedef struct DjvuDocument { ddjvu_context_t *context; ddjvu_document_t *doc_ref; - int pages; } DjvuDocument; typedef struct DjvuPage { @@ -90,7 +89,6 @@ static int openDocument(lua_State *L) { return luaL_error(L, "cannot open DJVU file <%s>", filename); } - doc->pages = ddjvu_document_get_pagenum(doc->doc_ref); return 1; } @@ -109,7 +107,7 @@ static int closeDocument(lua_State *L) { static int getNumberOfPages(lua_State *L) { DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); - lua_pushinteger(L, doc->pages); + lua_pushinteger(L, ddjvu_document_get_pagenum(doc->doc_ref)); return 1; } @@ -175,8 +173,8 @@ static int openPage(lua_State *L) { DjvuDocument *doc = (DjvuDocument*) luaL_checkudata(L, 1, "djvudocument"); int pageno = luaL_checkint(L, 2); - if(pageno < 1 || pageno > doc->pages) { - return luaL_error(L, "cannot open page #%d, out of range (1-%d)", pageno, doc->pages); + 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)); } DjvuPage *page = (DjvuPage*) lua_newuserdata(L, sizeof(DjvuPage)); From b037208fb10cfe3d8c929a7088fc57bfcdf46d58 Mon Sep 17 00:00:00 2001 From: HW Date: Tue, 20 Mar 2012 00:03:35 +0100 Subject: [PATCH 11/12] factored pages count out, better error and password handling --- pdf.c | 66 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/pdf.c b/pdf.c index 9f4935420..b335d65c7 100644 --- a/pdf.c +++ b/pdf.c @@ -24,7 +24,6 @@ typedef struct PdfDocument { fz_document *xref; fz_context *context; - int pages; } PdfDocument; typedef struct PdfPage { @@ -38,8 +37,7 @@ typedef struct PdfPage { static int openDocument(lua_State *L) { char *filename = strdup(luaL_checkstring(L, 1)); - char *password = strdup(luaL_checkstring(L, 2)); - int cachesize = luaL_optint(L, 3, 64 << 20); // 64 MB limit default + int cachesize = luaL_optint(L, 2, 64 << 20); // 64 MB limit default PdfDocument *doc = (PdfDocument*) lua_newuserdata(L, sizeof(PdfDocument)); @@ -53,19 +51,28 @@ static int openDocument(lua_State *L) { } fz_catch(doc->context) { free(filename); - free(password); - return luaL_error(L, "cannot open PDF file <%s>", filename); + return luaL_error(L, "cannot open PDF file"); } - if(fz_needs_password(doc->xref)) { - if (!fz_authenticate_password(doc->xref, password)) { - free(filename); - free(password); - return luaL_error(L, "cannot authenticate"); - } - } - doc->pages = fz_count_pages(doc->xref); free(filename); + return 1; +} + +static int needsPassword(lua_State *L) { + PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); + lua_pushboolean(L, fz_needs_password(doc->xref)); + return 1; +} + +static int authenticatePassword(lua_State *L) { + PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); + char *password = strdup(luaL_checkstring(L, 2)); + + if (!fz_authenticate_password(doc->xref, password)) { + lua_pushboolean(L, 0); + } else { + lua_pushboolean(L, 1); + } free(password); return 1; } @@ -85,7 +92,12 @@ static int closeDocument(lua_State *L) { static int getNumberOfPages(lua_State *L) { PdfDocument *doc = (PdfDocument*) luaL_checkudata(L, 1, "pdfdocument"); - lua_pushinteger(L, doc->pages); + fz_try(doc->context) { + lua_pushinteger(L, fz_count_pages(doc->xref)); + } + fz_catch(doc->context) { + return luaL_error(L, "cannot access page tree"); + } return 1; } @@ -148,24 +160,24 @@ static int openPage(lua_State *L) { int pageno = luaL_checkint(L, 2); - if(pageno < 1 || pageno > doc->pages) { - return luaL_error(L, "cannot open page #%d, out of range (1-%d)", pageno, doc->pages); - } - - PdfPage *page = (PdfPage*) lua_newuserdata(L, sizeof(PdfPage)); - - luaL_getmetatable(L, "pdfpage"); - lua_setmetatable(L, -2); - fz_try(doc->context) { + if(pageno < 1 || pageno > fz_count_pages(doc->xref)) { + return luaL_error(L, "cannot open page #%d, out of range (1-%d)", + pageno, fz_count_pages(doc->xref)); + } + + PdfPage *page = (PdfPage*) lua_newuserdata(L, sizeof(PdfPage)); + + luaL_getmetatable(L, "pdfpage"); + lua_setmetatable(L, -2); + page->page = fz_load_page(doc->xref, pageno - 1); + + page->doc = doc; } fz_catch(doc->context) { return luaL_error(L, "cannot open page #%d", pageno); } - - page->doc = doc; - return 1; } @@ -288,6 +300,8 @@ static const struct luaL_Reg pdf_func[] = { }; static const struct luaL_Reg pdfdocument_meth[] = { + {"needsPassword", needsPassword}, + {"authenticatePassword", authenticatePassword}, {"openPage", openPage}, {"getPages", getNumberOfPages}, {"getTOC", getTableOfContent}, From 7e3e38be62dc88a7f9a64d5d4facfa18382d91c0 Mon Sep 17 00:00:00 2001 From: HW Date: Tue, 20 Mar 2012 00:10:19 +0100 Subject: [PATCH 12/12] Password input, handling for broken documents --- djvureader.lua | 8 ++++++-- pdfreader.lua | 29 ++++++++++++++++++++++++++--- reader.lua | 24 ++++++++++++++---------- unireader.lua | 9 ++++++++- 4 files changed, 54 insertions(+), 16 deletions(-) diff --git a/djvureader.lua b/djvureader.lua index 1b4b37697..0582073b9 100644 --- a/djvureader.lua +++ b/djvureader.lua @@ -5,6 +5,10 @@ DJVUReader = UniReader:new{} -- open a DJVU file and its settings store -- DJVU does not support password yet function DJVUReader:open(filename) - self.doc = djvu.openDocument(filename) - return self:loadSettings(filename) + local ok + ok, self.doc = pcall(djvu.openDocument, filename) + if not ok then + return ok, self.doc -- this will be the error message instead + end + return ok end diff --git a/pdfreader.lua b/pdfreader.lua index 2af16f1cb..ec4e1a105 100644 --- a/pdfreader.lua +++ b/pdfreader.lua @@ -1,9 +1,32 @@ require "unireader" +require "inputbox" PDFReader = UniReader:new{} -- open a PDF file and its settings store -function PDFReader:open(filename, password) - self.doc = pdf.openDocument(filename, password or "") - return self:loadSettings(filename) +function PDFReader:open(filename) + -- muPDF manages its own cache, set second parameter + -- to the maximum size you want it to grow + local ok + ok, self.doc = pcall(pdf.openDocument, filename, 64*1024*1024) + if not ok then + return false, self.doc -- will contain error message + end + if self.doc:needsPassword() then + local password = InputBox:input(height-100, 100, "Pass:") + if not password or not self.doc:authenticatePassword(password) then + self.doc:close() + self.doc = nil + return false, "wrong or missing password" + end + -- password wrong or not entered + end + local ok, err = pcall(self.doc.getPages, self.doc) + if not ok then + -- for PDFs, they might trigger errors later when accessing page tree + self.doc:close() + self.doc = nil + return false, "damaged page tree" + end + return true end diff --git a/reader.lua b/reader.lua index 83cc0bb1d..7afefa90f 100755 --- a/reader.lua +++ b/reader.lua @@ -35,21 +35,25 @@ longopts = { function openFile(filename) local file_type = string.lower(string.match(filename, ".+%.([^.]+)")) + local reader = nil if file_type == "djvu" then - if DJVUReader:open(filename) then - page_num = DJVUReader.settings:readsetting("last_page") or 1 - DJVUReader:goto(tonumber(page_num)) - reader_settings:savesetting("lastfile", filename) - return DJVUReader:inputloop() - end + reader = DJVUReader elseif file_type == "pdf" or file_type == "xps" or file_type == "cbz" then - if PDFReader:open(filename,"") then -- TODO: query for password - page_num = PDFReader.settings:readsetting("last_page") or 1 - PDFReader:goto(tonumber(page_num)) + reader = PDFReader + end + if reader then + local ok, err = reader:open(filename) + if ok then + reader:loadSettings(filename) + page_num = reader.settings:readsetting("last_page") or 1 + reader:goto(tonumber(page_num)) reader_settings:savesetting("lastfile", filename) - return PDFReader:inputloop() + return reader:inputloop() + else + -- TODO: error handling end end + return true -- on failed attempts, we signal to keep running end function showusage() diff --git a/unireader.lua b/unireader.lua index 27251a486..b738197a2 100644 --- a/unireader.lua +++ b/unireader.lua @@ -175,7 +175,11 @@ function UniReader:draworcache(no, preCache) -- #4 goal: we render next page, too. (TODO) -- ideally, this should be factored out and only be called when needed (TODO) - local page = self.doc:openPage(no) + local ok, page = pcall(self.doc.openPage, self.doc, no) + if not ok then + -- TODO: error handling + return nil + end local dc = self:setzoom(page) -- offset_x_in_page & offset_y_in_page is the offset within zoomed page @@ -433,6 +437,9 @@ end -- render and blit a page function UniReader:show(no) local pagehash, offset_x, offset_y = self:draworcache(no) + if not pagehash then + return + end self.pagehash = pagehash local bb = self.cache[pagehash].bb local dest_x = 0