mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Merge branch 'new_ui_code' of github.com:hwhw/kindlepdfviewer into new_ui_code
Conflicts: Makefile
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -13,3 +13,6 @@
|
||||
[submodule "luajit-2.0"]
|
||||
path = luajit-2.0
|
||||
url = http://luajit.org/git/luajit-2.0.git
|
||||
[submodule "libk2pdfopt"]
|
||||
path = libk2pdfopt
|
||||
url = git://github.com/chrox/libk2pdfopt.git
|
||||
|
||||
29
Makefile
29
Makefile
@@ -13,6 +13,7 @@ JPEGDIR=$(MUPDFDIR)/thirdparty/jpeg-9
|
||||
LFSDIR=luafilesystem
|
||||
|
||||
POPENNSDIR=popen-noshell
|
||||
K2PDFOPTLIBDIR=libk2pdfopt
|
||||
|
||||
# must point to directory with *.ttf fonts for crengine
|
||||
TTF_FONTS_DIR=$(MUPDFDIR)/fonts
|
||||
@@ -84,6 +85,7 @@ endif
|
||||
|
||||
# standard includes
|
||||
KPDFREADER_CFLAGS=$(CFLAGS) -I$(LUADIR)/src -I$(MUPDFDIR)/
|
||||
K2PDFOPT_CFLAGS=-I$(K2PDFOPTLIBDIR)/willuslib -I$(K2PDFOPTLIBDIR)/k2pdfoptlib -I$(K2PDFOPTLIBDIR)/
|
||||
|
||||
# enable tracing output:
|
||||
|
||||
@@ -114,19 +116,21 @@ LUALIB := $(LIBDIR)/libluajit-5.1.so.2
|
||||
|
||||
POPENNSLIB := $(POPENNSDIR)/libpopen_noshell.a
|
||||
|
||||
K2PDFOPTLIB := $(LIBDIR)/libk2pdfopt.so.1
|
||||
|
||||
all: kpdfview extr
|
||||
|
||||
VERSION?=$(shell git describe HEAD)
|
||||
kpdfview: kpdfview.o einkfb.o pdf.o k2pdfopt.o blitbuffer.o drawcontext.o input.o $(POPENNSLIB) util.o ft.o lfs.o mupdfimg.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) djvu.o $(DJVULIBS) cre.o $(CRENGINELIBS) pic.o pic_jpeg.o
|
||||
kpdfview: kpdfview.o einkfb.o pdf.o blitbuffer.o drawcontext.o koptcontext.o input.o $(POPENNSLIB) util.o ft.o lfs.o mupdfimg.o $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) djvu.o $(DJVULIBS) cre.o $(CRENGINELIBS) pic.o pic_jpeg.o
|
||||
echo $(VERSION) > git-rev
|
||||
$(CC) \
|
||||
$(CFLAGS) \
|
||||
kpdfview.o \
|
||||
einkfb.o \
|
||||
pdf.o \
|
||||
k2pdfopt.o \
|
||||
blitbuffer.o \
|
||||
drawcontext.o \
|
||||
koptcontext.o \
|
||||
input.o \
|
||||
$(POPENNSLIB) \
|
||||
util.o \
|
||||
@@ -144,7 +148,7 @@ kpdfview: kpdfview.o einkfb.o pdf.o k2pdfopt.o blitbuffer.o drawcontext.o input.
|
||||
$(STATICLIBSTDCPP) \
|
||||
$(LDFLAGS) \
|
||||
-o $@ \
|
||||
-lm -ldl -lpthread -ldjvulibre -ljpeg -lluajit -L$(MUPDFLIBDIR) -L$(LIBDIR)\
|
||||
-lm -ldl -lpthread -lk2pdfopt -ldjvulibre -lluajit -ljpeg -L$(MUPDFLIBDIR) -L$(LIBDIR)\
|
||||
$(EMU_LDFLAGS) \
|
||||
$(DYNAMICLIBSTDCPP)
|
||||
|
||||
@@ -163,14 +167,14 @@ slider_watcher: slider_watcher.o $(POPENNSLIB)
|
||||
ft.o: %.o: %.c $(THIRDPARTYLIBS)
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) -I$(FREETYPEDIR)/include -I$(MUPDFDIR)/fitz $< -o $@
|
||||
|
||||
kpdfview.o pdf.o blitbuffer.o util.o drawcontext.o einkfb.o input.o mupdfimg.o: %.o: %.c
|
||||
blitbuffer.o util.o drawcontext.o einkfb.o input.o mupdfimg.o: %.o: %.c
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) $(EMU_CFLAGS) -I$(LFSDIR)/src $< -o $@
|
||||
|
||||
k2pdfopt.o: %.o: %.c
|
||||
$(CC) -c -I$(MUPDFDIR)/ -I$(DJVUDIR)/ $(CFLAGS) $< -o $@
|
||||
kpdfview.o koptcontext.o pdf.o: %.o: %.c
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) $(K2PDFOPT_CFLAGS) $(EMU_CFLAGS) -I$(LFSDIR)/src $< -o $@
|
||||
|
||||
djvu.o: %.o: %.c
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) -I$(DJVUDIR)/ $< -o $@
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) $(K2PDFOPT_CFLAGS) -I$(DJVUDIR)/ $< -o $@
|
||||
|
||||
pic.o: %.o: %.c
|
||||
$(CC) -c $(KPDFREADER_CFLAGS) $< -o $@
|
||||
@@ -232,6 +236,7 @@ cleanthirdparty:
|
||||
rm -f $(MUPDFDIR)/fontdump.host
|
||||
rm -f $(MUPDFDIR)/cmapdump.host
|
||||
$(MAKE) -C $(POPENNSDIR) clean
|
||||
$(MAKE) -C $(K2PDFOPTLIBDIR) clean
|
||||
|
||||
$(MUPDFDIR)/fontdump.host:
|
||||
CFLAGS="$(HOSTCFLAGS)" $(MAKE) -C mupdf build="release" CC="$(HOSTCC)" $(MUPDFTARGET)/fontdump
|
||||
@@ -276,7 +281,12 @@ endif
|
||||
$(POPENNSLIB):
|
||||
$(MAKE) -C $(POPENNSDIR) CC="$(CC)" AR="$(AR)"
|
||||
|
||||
thirdparty: $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) $(CRENGINELIBS) $(POPENNSLIB)
|
||||
$(K2PDFOPTLIB):
|
||||
$(MAKE) -C $(K2PDFOPTLIBDIR) BUILDMODE=shared CC="$(CC)" CFLAGS="$(CFLAGS) -O3" AR="$(AR)" all
|
||||
test -d $(LIBDIR) || mkdir $(LIBDIR)
|
||||
cp -a $(K2PDFOPTLIBDIR)/libk2pdfopt.so* $(LIBDIR)
|
||||
|
||||
thirdparty: $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) $(CRENGINELIBS) $(POPENNSLIB) $(K2PDFOPTLIB)
|
||||
|
||||
INSTALL_DIR=kindlepdfviewer
|
||||
|
||||
@@ -292,8 +302,7 @@ customupdate: all
|
||||
mkdir -p $(INSTALL_DIR)/{history,screenshots,clipboard,libs}
|
||||
cp -p README.md COPYING kpdfview extr kpdf.sh $(LUA_FILES) $(INSTALL_DIR)
|
||||
mkdir $(INSTALL_DIR)/data
|
||||
cp -L libs/libdjvulibre.so.21 $(INSTALL_DIR)/libs
|
||||
cp -L $(LUALIB) $(INSTALL_DIR)/libs
|
||||
cp -L $(LUALIB) libs/libdjvulibre.so.21 $(K2PDFOPTLIB) $(INSTALL_DIR)/libs
|
||||
$(STRIP) --strip-unneeded $(INSTALL_DIR)/libs/*
|
||||
cp -rpL data/*.css $(INSTALL_DIR)/data
|
||||
cp -rpL fonts $(INSTALL_DIR)
|
||||
|
||||
99
djvu.c
99
djvu.c
@@ -18,11 +18,14 @@
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <libdjvu/miniexp.h>
|
||||
#include <libdjvu/ddjvuapi.h>
|
||||
|
||||
#include "blitbuffer.h"
|
||||
#include "drawcontext.h"
|
||||
#include "koptcontext.h"
|
||||
#include "k2pdfopt.h"
|
||||
#include "djvu.h"
|
||||
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
@@ -471,46 +474,82 @@ static int closePage(lua_State *L) {
|
||||
}
|
||||
|
||||
static int reflowPage(lua_State *L) {
|
||||
|
||||
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
|
||||
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
|
||||
KOPTContext *kctx = (KOPTContext*) luaL_checkudata(L, 2, "koptcontext");
|
||||
ddjvu_render_mode_t mode = (int) luaL_checkint(L, 3);
|
||||
int width = luaL_checkint(L, 4); // framebuffer size
|
||||
int height = luaL_checkint(L, 5);
|
||||
double font_size = luaL_checknumber(L, 6);
|
||||
double page_margin = luaL_checknumber(L, 7);
|
||||
double line_spacing = luaL_checknumber(L, 8);
|
||||
double word_spacing = luaL_checknumber(L, 9);
|
||||
int text_wrap = luaL_checkint(L, 10);
|
||||
int straighten = luaL_checkint(L, 11);
|
||||
int justification = luaL_checkint(L, 12);
|
||||
int columns = luaL_checkint(L, 13);
|
||||
double contrast = luaL_checknumber(L, 14);
|
||||
int rotation = luaL_checknumber(L, 15);
|
||||
ddjvu_rect_t prect;
|
||||
ddjvu_rect_t rrect;
|
||||
|
||||
k2pdfopt_set_params(width, height, font_size, page_margin, line_spacing, word_spacing, \
|
||||
text_wrap, straighten, justification, columns, contrast, rotation);
|
||||
int px, py, pw, ph, rx, ry, rw, rh, idpi, status;
|
||||
double zoom = kctx->zoom;
|
||||
double dpi = 250*zoom;
|
||||
|
||||
k2pdfopt_djvu_reflow(page->page_ref, page->doc->context, mode, page->doc->pixelformat);
|
||||
k2pdfopt_rfbmp_size(&width, &height);
|
||||
k2pdfopt_rfbmp_zoom(&dc->zoom);
|
||||
px = 0;
|
||||
py = 0;
|
||||
pw = ddjvu_page_get_width(page->page_ref);
|
||||
ph = ddjvu_page_get_height(page->page_ref);
|
||||
idpi = ddjvu_page_get_resolution(page->page_ref);
|
||||
prect.x = px;
|
||||
prect.y = py;
|
||||
|
||||
lua_pushnumber(L, (double)width);
|
||||
lua_pushnumber(L, (double)height);
|
||||
lua_pushnumber(L, (double)dc->zoom);
|
||||
rx = (int)kctx->bbox.x0;
|
||||
ry = (int)kctx->bbox.y0;
|
||||
rw = (int)(kctx->bbox.x1 - kctx->bbox.x0);
|
||||
rh = (int)(kctx->bbox.y1 - kctx->bbox.y0);
|
||||
|
||||
return 3;
|
||||
do {
|
||||
prect.w = pw * dpi / idpi;
|
||||
prect.h = ph * dpi / idpi;
|
||||
rrect.x = rx * dpi / idpi;
|
||||
rrect.y = ry * dpi / idpi;
|
||||
rrect.w = rw * dpi / idpi;
|
||||
rrect.h = rh * dpi / idpi;
|
||||
printf("rendering page:%d,%d,%d,%d dpi:%.0f idpi:%.0d\n",rrect.x,rrect.y,rrect.w,rrect.h,dpi,idpi);
|
||||
kctx->zoom = zoom;
|
||||
zoom *= kctx->shrink_factor;
|
||||
dpi *= kctx->shrink_factor;
|
||||
} while (rrect.w > kctx->read_max_width | rrect.h > kctx->read_max_height);
|
||||
|
||||
WILLUSBITMAP *src = malloc(sizeof(WILLUSBITMAP));
|
||||
bmp_init(src);
|
||||
src->width = rrect.w;
|
||||
src->height = rrect.h;
|
||||
src->bpp = 8;
|
||||
|
||||
bmp_alloc(src);
|
||||
if (src->bpp == 8) {
|
||||
int ii;
|
||||
for (ii = 0; ii < 256; ii++)
|
||||
src->red[ii] = src->blue[ii] = src->green[ii] = ii;
|
||||
}
|
||||
|
||||
ddjvu_format_set_row_order(page->doc->pixelformat, 1);
|
||||
|
||||
status = ddjvu_page_render(page->page_ref, mode, &prect, &rrect, page->doc->pixelformat,
|
||||
bmp_bytewidth(src), (char *) src->data);
|
||||
|
||||
kctx->src = src;
|
||||
if (kctx->precache) {
|
||||
pthread_t rf_thread;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create(&rf_thread, &attr, k2pdfopt_reflow_bmp, (void*) kctx);
|
||||
pthread_attr_destroy(&attr);
|
||||
} else {
|
||||
k2pdfopt_reflow_bmp(kctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drawReflowedPage(lua_State *L) {
|
||||
uint8_t *pmptr = NULL;
|
||||
|
||||
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
|
||||
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 2, "koptcontext");
|
||||
BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer");
|
||||
|
||||
uint8_t *koptr = kc->data;
|
||||
uint8_t *bbptr = bb->data;
|
||||
k2pdfopt_rfbmp_ptr(&pmptr);
|
||||
|
||||
int x_offset = 0;
|
||||
int y_offset = 0;
|
||||
@@ -520,12 +559,12 @@ static int drawReflowedPage(lua_State *L) {
|
||||
for(y = y_offset; y < bb->h; y++) {
|
||||
for(x = x_offset/2; x < (bb->w/2); x++) {
|
||||
int p = x*2 - x_offset;
|
||||
bbptr[x] = (((pmptr[p + 1] & 0xF0) >> 4) | (pmptr[p] & 0xF0)) ^ 0xFF;
|
||||
bbptr[x] = (((koptr[p + 1] & 0xF0) >> 4) | (koptr[p] & 0xF0)) ^ 0xFF;
|
||||
}
|
||||
bbptr += bb->pitch;
|
||||
pmptr += bb->w;
|
||||
koptr += bb->w;
|
||||
if (bb->w & 1) {
|
||||
bbptr[x] = 255 - (pmptr[x*2] & 0xF0);
|
||||
bbptr[x] = 255 - (koptr[x*2] & 0xF0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
7015
k2pdfopt.c
7015
k2pdfopt.c
File diff suppressed because it is too large
Load Diff
41
k2pdfopt.h
41
k2pdfopt.h
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
** k2pdfopt.h K2pdfopt optimizes PDF/DJVU files for mobile e-readers
|
||||
** (e.g. the Kindle) and smartphones. It works well on
|
||||
** multi-column PDF/DJVU files. K2pdfopt is freeware.
|
||||
**
|
||||
** Copyright (C) 2012 http://willus.com
|
||||
**
|
||||
** This program is free software: you can redistribute it and/or modify
|
||||
** it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Affero General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef _K2PDFOPT_H
|
||||
#define _K2PDFOPT_H
|
||||
|
||||
#include <fitz/fitz-internal.h>
|
||||
#include <libdjvu/ddjvuapi.h>
|
||||
|
||||
void k2pdfopt_set_params(int bb_width, int bb_height, \
|
||||
double font_size, double page_margin, \
|
||||
double line_space, double word_space, \
|
||||
int wrapping, int straighten, int justification, \
|
||||
int columns, double contrast, int rotation);
|
||||
void k2pdfopt_mupdf_reflow(fz_document *doc, fz_page *page, fz_context *ctx);
|
||||
void k2pdfopt_djvu_reflow(ddjvu_page_t *page, ddjvu_context_t *ctx, ddjvu_render_mode_t mode, ddjvu_format_t *fmt);
|
||||
void k2pdfopt_rfbmp_size(int *width, int *height);
|
||||
void k2pdfopt_rfbmp_ptr(unsigned char** bmp_ptr_ptr);
|
||||
void k2pdfopt_rfbmp_zoom(double *zoom);
|
||||
|
||||
#endif
|
||||
|
||||
278
koptcontext.c
Normal file
278
koptcontext.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
KindlePDFViewer: a KOPTContext abstraction
|
||||
Copyright (C) 2012 Huang Xin <chrox.huang@gmail.com>
|
||||
|
||||
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 "koptcontext.h"
|
||||
|
||||
static int newKOPTContext(lua_State *L) {
|
||||
int trim = 1;
|
||||
int wrap = 1;
|
||||
int indent = 1;
|
||||
int rotate = 0;
|
||||
int columns = 2;
|
||||
int offset_x = 0;
|
||||
int offset_y = 0;
|
||||
int dev_width = 600;
|
||||
int dev_height = 800;
|
||||
int page_width = 600;
|
||||
int page_height = 800;
|
||||
int straighten = 0;
|
||||
int justification = -1;
|
||||
int read_max_width = 3000;
|
||||
int read_max_height = 4000;
|
||||
|
||||
double zoom = 1.0;
|
||||
double margin = 0.06;
|
||||
double quality = 1.0;
|
||||
double contrast = 1.0;
|
||||
double defect_size = 1.0;
|
||||
double line_spacing = 1.2;
|
||||
double word_spacing = 1.375;
|
||||
double shrink_factor = 0.9;
|
||||
|
||||
uint8_t *data = NULL;
|
||||
BBox bbox = {0, 0, 0, 0};
|
||||
WILLUSBITMAP *src;
|
||||
int precache = 0;
|
||||
|
||||
KOPTContext *kc = (KOPTContext*) lua_newuserdata(L, sizeof(KOPTContext));
|
||||
|
||||
kc->trim = trim;
|
||||
kc->wrap = wrap;
|
||||
kc->indent = indent;
|
||||
kc->rotate = rotate;
|
||||
kc->columns = columns;
|
||||
kc->offset_x = offset_x;
|
||||
kc->offset_y = offset_y;
|
||||
kc->dev_width = dev_width;
|
||||
kc->dev_height = dev_height;
|
||||
kc->page_width = page_width;
|
||||
kc->page_height = page_height;
|
||||
kc->straighten = straighten;
|
||||
kc->justification = justification;
|
||||
kc->read_max_width = read_max_width;
|
||||
kc->read_max_height = read_max_height;
|
||||
|
||||
kc->zoom = zoom;
|
||||
kc->margin = margin;
|
||||
kc->quality = quality;
|
||||
kc->contrast = contrast;
|
||||
kc->defect_size = defect_size;
|
||||
kc->line_spacing = line_spacing;
|
||||
kc->word_spacing = word_spacing;
|
||||
kc->shrink_factor = shrink_factor;
|
||||
|
||||
kc->data = data;
|
||||
kc->bbox = bbox;
|
||||
kc->src = src;
|
||||
kc->precache = precache;
|
||||
|
||||
luaL_getmetatable(L, "koptcontext");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kcSetBBox(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->bbox.x0 = luaL_checknumber(L, 2);
|
||||
kc->bbox.y0 = luaL_checknumber(L, 3);
|
||||
kc->bbox.x1 = luaL_checknumber(L, 4);
|
||||
kc->bbox.y1 = luaL_checknumber(L, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetTrim(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->trim = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcGetTrim(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
lua_pushinteger(L, kc->trim);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kcSetWrap(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->wrap = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetIndent(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->indent = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetRotate(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->rotate = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetColumns(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->columns = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetOffset(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->offset_x = luaL_checkint(L, 2);
|
||||
kc->offset_y = luaL_checkint(L, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcGetOffset(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
lua_pushinteger(L, kc->offset_x);
|
||||
lua_pushinteger(L, kc->offset_y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int kcSetDeviceDim(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->dev_width = luaL_checkint(L, 2);
|
||||
kc->dev_height = luaL_checkint(L, 3);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcGetPageDim(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
lua_pushinteger(L, kc->page_width);
|
||||
lua_pushinteger(L, kc->page_height);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int kcSetStraighten(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->straighten = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetJustification(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->justification = luaL_checkint(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetZoom(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->zoom = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcGetZoom(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
lua_pushnumber(L, kc->zoom);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int kcSetMargin(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->margin = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetQuality(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->quality = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetContrast(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->contrast = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetDefectSize(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->defect_size = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetLineSpacing(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->line_spacing = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetWordSpacing(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->word_spacing = luaL_checknumber(L, 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcSetPreCache(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
kc->precache = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kcIsPreCache(lua_State *L) {
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 1, "koptcontext");
|
||||
lua_pushinteger(L, kc->precache);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg koptcontext_meth[] = {
|
||||
{"setBBox", kcSetBBox},
|
||||
{"setTrim", kcSetTrim},
|
||||
{"getTrim", kcGetTrim},
|
||||
{"setWrap", kcSetWrap},
|
||||
{"setIndent", kcSetIndent},
|
||||
{"setRotate", kcSetRotate},
|
||||
{"setColumns", kcSetColumns},
|
||||
{"setOffset", kcSetOffset},
|
||||
{"getOffset", kcGetOffset},
|
||||
{"setDeviceDim", kcSetDeviceDim},
|
||||
{"getPageDim", kcGetPageDim},
|
||||
{"setStraighten", kcSetStraighten},
|
||||
{"setJustification", kcSetJustification},
|
||||
|
||||
{"setZoom", kcSetZoom},
|
||||
{"getZoom", kcGetZoom},
|
||||
{"setMargin", kcSetMargin},
|
||||
{"setQuality", kcSetQuality},
|
||||
{"setContrast", kcSetContrast},
|
||||
{"setDefectSize", kcSetDefectSize},
|
||||
{"setLineSpacing", kcSetLineSpacing},
|
||||
{"setWordSpacing", kcSetWordSpacing},
|
||||
|
||||
{"setPreCache", kcSetPreCache},
|
||||
{"isPreCache", kcIsPreCache},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static const struct luaL_Reg koptcontext_func[] = {
|
||||
{"new", newKOPTContext},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int luaopen_koptcontext(lua_State *L) {
|
||||
luaL_newmetatable(L, "koptcontext");
|
||||
lua_pushstring(L, "__index");
|
||||
lua_pushvalue(L, -2);
|
||||
lua_settable(L, -3);
|
||||
luaL_register(L, NULL, koptcontext_meth);
|
||||
lua_pop(L, 1);
|
||||
luaL_register(L, "KOPTContext", koptcontext_func);
|
||||
return 1;
|
||||
}
|
||||
27
koptcontext.h
Normal file
27
koptcontext.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
KindlePDFViewer: a KOPTContext abstraction
|
||||
Copyright (C) 2012 Huang Xin <chrox.huang@gmail.com>
|
||||
|
||||
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 _KOPTCONTEXT_H
|
||||
#define _KOPTCONTEXT_H
|
||||
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
#include <lauxlib.h>
|
||||
#include "koptreflow.h"
|
||||
|
||||
int luaopen_koptcontext(lua_State *L);
|
||||
#endif
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "blitbuffer.h"
|
||||
#include "drawcontext.h"
|
||||
#include "koptcontext.h"
|
||||
#include "pdf.h"
|
||||
#include "mupdfimg.h"
|
||||
#include "djvu.h"
|
||||
@@ -94,6 +95,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
luaopen_blitbuffer(L);
|
||||
luaopen_drawcontext(L);
|
||||
luaopen_koptcontext(L);
|
||||
luaopen_einkfb(L);
|
||||
luaopen_pdf(L);
|
||||
luaopen_djvu(L);
|
||||
|
||||
1
libk2pdfopt
Submodule
1
libk2pdfopt
Submodule
Submodule libk2pdfopt added at d9ed4f0b5d
152
pdf.c
152
pdf.c
@@ -15,15 +15,18 @@
|
||||
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 <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <pthread.h>
|
||||
#include <fitz/fitz-internal.h>
|
||||
|
||||
#include "blitbuffer.h"
|
||||
#include "drawcontext.h"
|
||||
#include "koptcontext.h"
|
||||
#include "k2pdfopt.h"
|
||||
#include "pdf.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
typedef struct PdfDocument {
|
||||
fz_document *xref;
|
||||
@@ -511,45 +514,126 @@ static int closePage(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bmpmupdf.c from willuslib */
|
||||
static int bmpmupdf_pixmap_to_bmp(WILLUSBITMAP *bmp, fz_context *ctx, fz_pixmap *pixmap) {
|
||||
unsigned char *p;
|
||||
int ncomp, i, row, col;
|
||||
|
||||
bmp->width = fz_pixmap_width(ctx, pixmap);
|
||||
bmp->height = fz_pixmap_height(ctx, pixmap);
|
||||
ncomp = fz_pixmap_components(ctx, pixmap);
|
||||
/* Has to be 8-bit or RGB */
|
||||
if (ncomp != 2 && ncomp != 4)
|
||||
return (-1);
|
||||
bmp->bpp = (ncomp == 2) ? 8 : 24;
|
||||
bmp_alloc(bmp);
|
||||
if (ncomp == 2)
|
||||
for (i = 0; i < 256; i++)
|
||||
bmp->red[i] = bmp->green[i] = bmp->blue[i] = i;
|
||||
p = fz_pixmap_samples(ctx, pixmap);
|
||||
if (ncomp == 1)
|
||||
for (row = 0; row < bmp->height; row++) {
|
||||
unsigned char *dest;
|
||||
dest = bmp_rowptr_from_top(bmp, row);
|
||||
memcpy(dest, p, bmp->width);
|
||||
p += bmp->width;
|
||||
}
|
||||
else if (ncomp == 2)
|
||||
for (row = 0; row < bmp->height; row++) {
|
||||
unsigned char *dest;
|
||||
dest = bmp_rowptr_from_top(bmp, row);
|
||||
for (col = 0; col < bmp->width; col++, dest++, p += 2)
|
||||
dest[0] = p[0];
|
||||
}
|
||||
else
|
||||
for (row = 0; row < bmp->height; row++) {
|
||||
unsigned char *dest;
|
||||
dest = bmp_rowptr_from_top(bmp, row);
|
||||
for (col = 0; col < bmp->width;
|
||||
col++, dest += ncomp - 1, p += ncomp)
|
||||
memcpy(dest, p, ncomp - 1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int reflowPage(lua_State *L) {
|
||||
|
||||
PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage");
|
||||
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
|
||||
int width = luaL_checkint(L, 4); // framebuffer size
|
||||
int height = luaL_checkint(L, 5);
|
||||
double font_size = luaL_checknumber(L, 6);
|
||||
double page_margin = luaL_checknumber(L, 7);
|
||||
double line_spacing = luaL_checknumber(L, 8);
|
||||
double word_spacing = luaL_checknumber(L, 9);
|
||||
int text_wrap = luaL_checkint(L, 10);
|
||||
int straighten = luaL_checkint(L, 11);
|
||||
int justification = luaL_checkint(L, 12);
|
||||
int columns = luaL_checkint(L, 13);
|
||||
double contrast = luaL_checknumber(L, 14);
|
||||
int rotation = luaL_checknumber(L, 15);
|
||||
KOPTContext *kctx = (KOPTContext*) luaL_checkudata(L, 2, "koptcontext");
|
||||
fz_device *dev;
|
||||
fz_pixmap *pix;
|
||||
fz_rect bounds,bounds2;
|
||||
fz_matrix ctm;
|
||||
fz_bbox bbox;
|
||||
|
||||
k2pdfopt_set_params(width, height, font_size, page_margin, line_spacing, word_spacing, \
|
||||
text_wrap, straighten, justification, columns, contrast, rotation);
|
||||
k2pdfopt_mupdf_reflow(page->doc->xref, page->page, page->doc->context);
|
||||
k2pdfopt_rfbmp_size(&width, &height);
|
||||
k2pdfopt_rfbmp_zoom(&dc->zoom);
|
||||
pix = NULL;
|
||||
fz_var(pix);
|
||||
bounds.x0 = kctx->bbox.x0;
|
||||
bounds.y0 = kctx->bbox.y0;
|
||||
bounds.x1 = kctx->bbox.x1;
|
||||
bounds.y1 = kctx->bbox.y1;
|
||||
|
||||
lua_pushnumber(L, (double)width);
|
||||
lua_pushnumber(L, (double)height);
|
||||
lua_pushnumber(L, (double)dc->zoom);
|
||||
double dpp,zoom;
|
||||
zoom = kctx->zoom;
|
||||
double dpi = 250*zoom*kctx->quality;
|
||||
|
||||
return 3;
|
||||
do {
|
||||
dpp = dpi / 72.;
|
||||
ctm = fz_scale(dpp, dpp);
|
||||
// ctm=fz_concat(ctm,fz_rotate(rotation));
|
||||
bounds2 = fz_transform_rect(ctm, bounds);
|
||||
bbox = fz_round_rect(bounds2);
|
||||
printf("reading page:%d,%d,%d,%d zoom:%.2f dpi:%.0f\n",bbox.x0,bbox.y0,bbox.x1,bbox.y1,zoom,dpi);
|
||||
kctx->zoom = zoom;
|
||||
zoom *= kctx->shrink_factor;
|
||||
dpi *= kctx->shrink_factor;
|
||||
} while (bbox.x1 > kctx->read_max_width | bbox.y1 > kctx->read_max_height);
|
||||
|
||||
pix = fz_new_pixmap_with_bbox(page->doc->context, fz_device_gray, bbox);
|
||||
fz_clear_pixmap_with_value(page->doc->context, pix, 0xff);
|
||||
dev = fz_new_draw_device(page->doc->context, pix);
|
||||
|
||||
#ifdef MUPDF_TRACE
|
||||
fz_device *tdev;
|
||||
fz_try(page->doc->context) {
|
||||
tdev = fz_new_trace_device(page->doc->context);
|
||||
fz_run_page(page->doc->xref, page->page, tdev, ctm, NULL);
|
||||
}
|
||||
fz_always(page->doc->context) {
|
||||
fz_free_device(tdev);
|
||||
}
|
||||
#endif
|
||||
|
||||
fz_run_page(page->doc->xref, page->page, dev, ctm, NULL);
|
||||
fz_free_device(dev);
|
||||
|
||||
WILLUSBITMAP *src = malloc(sizeof(WILLUSBITMAP));
|
||||
bmp_init(src);
|
||||
|
||||
int status = bmpmupdf_pixmap_to_bmp(src, page->doc->context, pix);
|
||||
fz_drop_pixmap(page->doc->context, pix);
|
||||
|
||||
kctx->src = src;
|
||||
if (kctx->precache) {
|
||||
pthread_t rf_thread;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_create( &rf_thread, &attr, k2pdfopt_reflow_bmp, (void*) kctx);
|
||||
pthread_attr_destroy(&attr);
|
||||
} else {
|
||||
k2pdfopt_reflow_bmp(kctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int drawReflowedPage(lua_State *L) {
|
||||
uint8_t *pmptr = NULL;
|
||||
|
||||
PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage");
|
||||
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
|
||||
KOPTContext *kc = (KOPTContext*) luaL_checkudata(L, 2, "koptcontext");
|
||||
BlitBuffer *bb = (BlitBuffer*) luaL_checkudata(L, 3, "blitbuffer");
|
||||
|
||||
uint8_t *koptr = kc->data;
|
||||
uint8_t *bbptr = bb->data;
|
||||
k2pdfopt_rfbmp_ptr(&pmptr);
|
||||
|
||||
int x_offset = 0;
|
||||
int y_offset = 0;
|
||||
@@ -559,12 +643,12 @@ static int drawReflowedPage(lua_State *L) {
|
||||
for(y = y_offset; y < bb->h; y++) {
|
||||
for(x = x_offset/2; x < (bb->w/2); x++) {
|
||||
int p = x*2 - x_offset;
|
||||
bbptr[x] = (((pmptr[p + 1] & 0xF0) >> 4) | (pmptr[p] & 0xF0)) ^ 0xFF;
|
||||
bbptr[x] = (((koptr[p + 1] & 0xF0) >> 4) | (koptr[p] & 0xF0)) ^ 0xFF;
|
||||
}
|
||||
bbptr += bb->pitch;
|
||||
pmptr += bb->w;
|
||||
koptr += bb->w;
|
||||
if (bb->w & 1) {
|
||||
bbptr[x] = 255 - (pmptr[x*2] & 0xF0);
|
||||
bbptr[x] = 255 - (koptr[x*2] & 0xF0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user