mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge branch 'master' of github.com:hwhw/kindlepdfviewer into djvu-highlight
Conflicts: blitbuffer.c unireader.lua
This commit is contained in:
8
Makefile
8
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++
|
||||
@@ -62,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 \
|
||||
@@ -85,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
|
||||
@@ -133,7 +135,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
|
||||
|
||||
|
||||
@@ -423,12 +423,12 @@ static int invertRect(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},
|
||||
|
||||
114
djvu.c
114
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))
|
||||
@@ -30,7 +31,6 @@
|
||||
typedef struct DjvuDocument {
|
||||
ddjvu_context_t *context;
|
||||
ddjvu_document_t *doc_ref;
|
||||
int pages;
|
||||
} DjvuDocument;
|
||||
|
||||
typedef struct DjvuPage {
|
||||
@@ -40,14 +40,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)
|
||||
{
|
||||
@@ -97,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;
|
||||
}
|
||||
|
||||
@@ -116,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;
|
||||
}
|
||||
|
||||
@@ -177,84 +168,13 @@ 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");
|
||||
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));
|
||||
@@ -534,13 +454,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},
|
||||
{"newDC", newDrawContext},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct luaL_reg djvudocument_meth[] = {
|
||||
static const struct luaL_Reg djvudocument_meth[] = {
|
||||
{"openPage", openPage},
|
||||
{"getPages", getNumberOfPages},
|
||||
{"getTOC", getTableOfContent},
|
||||
@@ -550,7 +469,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},
|
||||
@@ -559,18 +478,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");
|
||||
@@ -586,13 +493,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;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,16 @@
|
||||
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
|
||||
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
|
||||
|
||||
function DJVUReader:_isWordInScreenRange(w)
|
||||
|
||||
117
drawcontext.c
Normal file
117
drawcontext.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
KindlePDFViewer: a DC abstraction
|
||||
Copyright (C) 2012 Hans-Werner Hilse <hilse@web.de>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
35
drawcontext.h
Normal file
35
drawcontext.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
KindlePDFViewer: a DC abstraction
|
||||
Copyright (C) 2012 Hans-Werner Hilse <hilse@web.de>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _DRAWCONTEXT_H
|
||||
#define _DRAWCONTEXT_H
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
typedef struct DrawContext {
|
||||
int rotate;
|
||||
double zoom;
|
||||
double gamma;
|
||||
int offset_x;
|
||||
int offset_y;
|
||||
} DrawContext;
|
||||
|
||||
int luaopen_drawcontext(lua_State *L);
|
||||
#endif
|
||||
|
||||
4
einkfb.c
4
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},
|
||||
|
||||
@@ -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
|
||||
|
||||
4
ft.c
4
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}
|
||||
|
||||
2
input.c
2
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},
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <lauxlib.h>
|
||||
|
||||
#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);
|
||||
|
||||
204
pdf.c
204
pdf.c
@@ -16,15 +16,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <fitz/fitz.h>
|
||||
#include <pdf/mupdf.h>
|
||||
|
||||
#include "blitbuffer.h"
|
||||
#include "drawcontext.h"
|
||||
#include "pdf.h"
|
||||
|
||||
typedef struct PdfDocument {
|
||||
pdf_document *xref;
|
||||
fz_document *xref;
|
||||
fz_context *context;
|
||||
int pages;
|
||||
} PdfDocument;
|
||||
|
||||
typedef struct PdfPage {
|
||||
@@ -32,47 +31,56 @@ typedef struct PdfPage {
|
||||
#ifdef USE_DISPLAY_LIST
|
||||
fz_display_list *list;
|
||||
#endif
|
||||
pdf_page *page;
|
||||
fz_page *page;
|
||||
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);
|
||||
char *filename = strdup(luaL_checkstring(L, 1));
|
||||
int cachesize = luaL_optint(L, 2, 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 = pdf_open_document(doc->context, filename);
|
||||
doc->xref = fz_open_document(doc->context, filename);
|
||||
}
|
||||
fz_catch(doc->context) {
|
||||
return luaL_error(L, "cannot open PDF file <%s>", filename);
|
||||
free(filename);
|
||||
return luaL_error(L, "cannot open PDF file");
|
||||
}
|
||||
|
||||
if(pdf_needs_password(doc->xref)) {
|
||||
if (!pdf_authenticate_password(doc->xref, password))
|
||||
return luaL_error(L, "cannot authenticate");
|
||||
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);
|
||||
}
|
||||
doc->pages = pdf_count_pages(doc->xref);
|
||||
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) {
|
||||
@@ -84,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;
|
||||
}
|
||||
|
||||
@@ -133,83 +146,13 @@ 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);
|
||||
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;
|
||||
|
||||
@@ -217,38 +160,38 @@ 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) {
|
||||
page->page = pdf_load_page(doc->xref, pageno - 1);
|
||||
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;
|
||||
}
|
||||
|
||||
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,11 +207,10 @@ 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);
|
||||
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);
|
||||
@@ -288,7 +230,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;
|
||||
@@ -312,7 +254,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);
|
||||
@@ -320,13 +261,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) {
|
||||
@@ -342,7 +283,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;
|
||||
@@ -353,13 +294,14 @@ static int drawPage(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct luaL_reg pdf_func[] = {
|
||||
static const struct luaL_Reg pdf_func[] = {
|
||||
{"openDocument", openDocument},
|
||||
{"newDC", newDrawContext},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct luaL_reg pdfdocument_meth[] = {
|
||||
static const struct luaL_Reg pdfdocument_meth[] = {
|
||||
{"needsPassword", needsPassword},
|
||||
{"authenticatePassword", authenticatePassword},
|
||||
{"openPage", openPage},
|
||||
{"getPages", getNumberOfPages},
|
||||
{"getTOC", getTableOfContent},
|
||||
@@ -368,7 +310,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},
|
||||
@@ -377,18 +319,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");
|
||||
@@ -402,12 +332,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;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
require "unireader"
|
||||
require "inputbox"
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
28
reader.lua
28
reader.lua
@@ -34,22 +34,26 @@ longopts = {
|
||||
}
|
||||
|
||||
function openFile(filename)
|
||||
local file_type = string.lower(string.match(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 = DJVUReader
|
||||
elseif file_type == "pdf" or file_type == "xps" or file_type == "cbz" then
|
||||
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 DJVUReader:inputloop()
|
||||
end
|
||||
elseif file_type == "pdf" 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_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()
|
||||
|
||||
@@ -58,10 +58,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
|
||||
@@ -90,13 +88,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
|
||||
@@ -182,8 +178,12 @@ 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 dc = self:setzoom(page, preCache)
|
||||
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
|
||||
-- they are always positive.
|
||||
@@ -289,7 +289,7 @@ end
|
||||
|
||||
-- set viewer state according to zoom state
|
||||
function UniReader:setzoom(page, preCache)
|
||||
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()
|
||||
@@ -444,6 +444,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
|
||||
|
||||
Reference in New Issue
Block a user