Merge pull request #493 from chrox/kopt-config

add config dialog for koptreader
Dobrica Pavlinušić 12 years ago
commit ac218923d3

@ -267,7 +267,7 @@ thirdparty: $(MUPDFLIBS) $(THIRDPARTYLIBS) $(LUALIB) $(DJVULIBS) $(CRENGINELIBS)
INSTALL_DIR=kindlepdfviewer
LUA_FILES=commands.lua crereader.lua dialog.lua djvureader.lua readerchooser.lua filechooser.lua filehistory.lua fileinfo.lua filesearcher.lua font.lua graphics.lua helppage.lua image.lua inputbox.lua keys.lua pdfreader.lua koptreader.lua picviewer.lua reader.lua rendertext.lua screen.lua selectmenu.lua settings.lua unireader.lua widget.lua
LUA_FILES=commands.lua crereader.lua dialog.lua djvureader.lua readerchooser.lua filechooser.lua filehistory.lua fileinfo.lua filesearcher.lua font.lua graphics.lua helppage.lua image.lua inputbox.lua keys.lua pdfreader.lua koptconfig.lua koptreader.lua picviewer.lua reader.lua rendertext.lua screen.lua selectmenu.lua settings.lua unireader.lua widget.lua
customupdate: all
# ensure that the binaries were built for ARM

@ -475,9 +475,13 @@ static int reflowPage(lua_State *L) {
DjvuPage *page = (DjvuPage*) luaL_checkudata(L, 1, "djvupage");
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
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 line_spacing = luaL_checknumber(L, 6);
double word_spacing = luaL_checknumber(L, 7);
int width, height;
k2pdfopt_djvu_reflow(page->page_ref, page->doc->context, mode, page->doc->pixelformat, dc->zoom);
k2pdfopt_djvu_reflow(page->page_ref, page->doc->context, mode, page->doc->pixelformat, dc->zoom, \
width, height, line_spacing, word_spacing);
k2pdfopt_rfbmp_size(&width, &height);
k2pdfopt_rfbmp_zoom(&dc->zoom);

@ -472,7 +472,8 @@ static void k2pdfopt_reflow_bmp(MASTERINFO *masterinfo, WILLUSBITMAP *src) {
}
void k2pdfopt_mupdf_reflow(fz_document *doc, fz_page *page, fz_context *ctx, \
double zoom, double gamma, double rot_deg) {
double zoom, double gamma, double rot_deg, \
int bb_width, int bb_height, double line_space, double word_space) {
fz_device *dev;
fz_pixmap *pix;
fz_rect bounds,bounds2;
@ -480,6 +481,14 @@ void k2pdfopt_mupdf_reflow(fz_document *doc, fz_page *page, fz_context *ctx, \
fz_bbox bbox;
WILLUSBITMAP _src, *src;
dst_userwidth = bb_width; // dst_width is adjusted in adjust_params_init
dst_userheight = bb_height;
vertical_line_spacing = line_space;
word_spacing = word_space;
printf("k2pdfopt_mupdf_reflow width:%d height:%d, line space:%.2f, word space:%.2f\n", \
bb_width,bb_height,vertical_line_spacing,word_spacing);
double dpp;
double dpi = 250*zoom;
do {
@ -533,11 +542,18 @@ 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, double zoom) {
ddjvu_render_mode_t mode, ddjvu_format_t *fmt, double zoom, \
int bb_width, int bb_height, double line_space, double word_space) {
WILLUSBITMAP _src, *src;
ddjvu_rect_t prect;
ddjvu_rect_t rrect;
int i, iw, ih, idpi, status;
dst_userwidth = bb_width; // dst_width is adjusted in adjust_params_init
dst_userheight = bb_height;
vertical_line_spacing = line_space;
word_spacing = word_space;
double dpi = 250*zoom;
while (!ddjvu_page_decoding_done(page))

@ -27,9 +27,11 @@
#include <libdjvu/ddjvuapi.h>
void k2pdfopt_mupdf_reflow(fz_document *doc, fz_page *page, fz_context *ctx, \
double dpi, double gamma, double rot_deg);
double zoom, double gamma, double rot_deg, int bb_width, int bb_height, \
double line_spacing, double word_spacing);
void k2pdfopt_djvu_reflow(ddjvu_page_t *page, ddjvu_context_t *ctx, \
ddjvu_render_mode_t mode, ddjvu_format_t *fmt, double dpi);
ddjvu_render_mode_t mode, ddjvu_format_t *fmt, double zoom, int bb_width, int bb_height, \
double line_spacing, double word_spacing);
void k2pdfopt_rfbmp_size(int *width, int *height);
void k2pdfopt_rfbmp_ptr(unsigned char** bmp_ptr_ptr);
void k2pdfopt_rfbmp_zoom(double *zoom);

@ -0,0 +1,226 @@
require "font"
require "keys"
require "settings"
KOPTOptions = {
{
name="line_spacing",
option_text="Line Spacing",
items_text={"small","medium","large"},
current_item=2,
text_dirty=true,
marker_dirty={true, true, true},
space={1.0, 1.2, 1.4}},
{
name="word_spacing",
option_text="Word Spacing",
items_text={"small","medium","large"},
current_item=2,
text_dirty=true,
marker_dirty={true, true, true},
space={0.2, 0.375, 0.5}},
}
KOPTConfig = {
-- UI constants
HEIGHT = 200, -- height
MARGIN_BOTTOM = 20, -- window bottom margin
MARGIN_HORISONTAL = 75, -- window horisontal margin
OPTION_PADDING_T = 50, -- options top padding
OPTION_PADDING_H = 50, -- options horisontal padding
OPTION_SPACING_V = 35, -- options vertical spacing
VALUE_PADDING_H = 150, -- values horisontal padding
VALUE_SPACING_H = 10, -- values horisontal spacing
OPT_NAME_FONT_SIZE = 20, -- option name font size
OPT_VALUE_FONT_SIZE = 16, -- option value font size
-- last pos text is drawn
text_pos = 0,
-- current selected option
current_option = 1,
-- page dirty
page_dirty = false,
}
configurable = {
font_size = 1.0,
page_margin = 0.06,
line_spacing = 1.2,
word_spacing = 0.375,
}
function KOPTConfig:drawBox(xpos, ypos, width, hight, bgcolor, bdcolor)
-- draw dialog border
local r = 6 -- round corners
fb.bb:paintRect(xpos, ypos+r, width, hight - 2*r, bgcolor)
blitbuffer.paintBorder(fb.bb, xpos, ypos, width, r, r, bgcolor, r)
blitbuffer.paintBorder(fb.bb, xpos, ypos+hight-2*r, width, r, r, bgcolor, r)
end
function KOPTConfig:drawOptionName(xpos, ypos, option_index, text, font_face, refresh)
local xpos, ypos = xpos+self.OPTION_PADDING_H, ypos+self.OPTION_PADDING_T
if KOPTOptions[option_index].text_dirty or refresh then
--Debug("drawing option name:", KOPTOptions[option_index].option_text)
renderUtf8Text(fb.bb, xpos, ypos+self.OPTION_SPACING_V*(option_index-1), font_face, text, true)
end
end
function KOPTConfig:drawOptionItem(xpos, ypos, option_index, item_index, text, font_face, refresh)
if item_index == 1 then
self.text_pos = 0
end
local xpos = xpos+self.OPTION_PADDING_H+self.VALUE_PADDING_H+self.VALUE_SPACING_H*(item_index-1)+self.text_pos
local ypos = ypos+self.OPTION_PADDING_T+self.OPTION_SPACING_V*(option_index-1)
if KOPTOptions[option_index].text_dirty or refresh then
--Debug("drawing option:", KOPTOptions[option_index].option_text, "item:", text)
renderUtf8Text(fb.bb, xpos, ypos, font_face, text, true)
end
local text_len = sizeUtf8Text(0, G_width, font_face, text, true).x
self.text_pos = self.text_pos + text_len
if KOPTOptions[option_index].marker_dirty[item_index] then
--Debug("drawing option:", KOPTOptions[option_index].option_text, "marker:", text)
if item_index == KOPTOptions[option_index].current_item then
fb.bb:paintRect(xpos, ypos+5, text_len, 3,(option_index == self.current_option) and 15 or 5)
fb:refresh(1, xpos, ypos+5, text_len, 3)
else
fb.bb:paintRect(xpos, ypos+5, text_len, 3, 3)
fb:refresh(1, xpos, ypos+5, text_len, 3)
end
KOPTOptions[option_index].marker_dirty[item_index] = false
end
end
function KOPTConfig:drawOptions(xpos, ypos, name_font, value_font, refresh)
local width, height = fb.bb:getWidth()-2*self.MARGIN_HORISONTAL, self.HEIGHT
for i=1,#KOPTOptions do
self:drawOptionName(xpos, ypos, i, KOPTOptions[i].option_text, name_font, refresh)
for j=1,#KOPTOptions[i].items_text do
self:drawOptionItem(xpos, ypos, i, j, KOPTOptions[i].items_text[j], value_font, refresh)
end
KOPTOptions[i].text_dirty = false
end
end
function KOPTConfig:config(callback, reader)
local kopt_callback = callback
local koptreader = reader
self:addAllCommands()
local name_font = Font:getFace("tfont", self.OPT_NAME_FONT_SIZE)
local value_font = Font:getFace("cfont", self.OPT_VALUE_FONT_SIZE)
-- base window coordinates
local width, height = fb.bb:getWidth()-2*self.MARGIN_HORISONTAL, self.HEIGHT
local topleft_x, topleft_y = self.MARGIN_HORISONTAL, fb.bb:getHeight()-self.MARGIN_BOTTOM-height
local botleft_x, botleft_y = self.MARGIN_HORISONTAL, topleft_y+height
self:drawBox(topleft_x, topleft_y, width, height, 3, 15)
self:drawOptions(topleft_x, topleft_y, name_font, value_font)
fb:refresh(1, topleft_x, topleft_y, width, height)
local ev, keydef, command, ret_code
while true do
configurable.line_spacing = KOPTOptions[1].space[KOPTOptions[1].current_item]
configurable.word_spacing = KOPTOptions[2].space[KOPTOptions[2].current_item]
--Debug("Line spacing:", configurable.line_spacing, "Word spacing:", configurable.word_spacing)
if self.page_dirty then
kopt_callback(koptreader, configurable)
self:drawBox(topleft_x, topleft_y, width, height, 3, 15)
self:drawOptions(topleft_x, topleft_y, name_font, value_font, true)
fb:refresh(1, topleft_x, topleft_y, width, height)
self.page_dirty = false
end
self:drawOptions(topleft_x, topleft_y, name_font, value_font)
ev = input.saveWaitForEvent()
ev.code = adjustKeyEvents(ev)
if ev.type == EV_KEY and ev.value ~= EVENT_VALUE_KEY_RELEASE then
keydef = Keydef:new(ev.code, getKeyModifier())
Debug("key pressed: "..tostring(keydef))
command = self.commands:getByKeydef(keydef)
if command ~= nil then
Debug("command to execute: "..tostring(command))
ret_code = command.func(self, keydef)
else
Debug("command not found: "..tostring(command))
end
if ret_code == "break" then
ret_code = nil
if self.final_choice then
return self.readers[self.final_choice]
else
return nil
end
end
end -- if
end -- while
end
-- add available commands
function KOPTConfig:addAllCommands()
self.commands = Commands:new{}
self.commands:add(KEY_FW_DOWN, nil, "joypad down",
"next item",
function(self)
local last_option = self.current_option
self.current_option = (self.current_option + #KOPTOptions + 1)%#KOPTOptions
self.current_option = (self.current_option == 0) and #KOPTOptions or self.current_option
last_option_item = KOPTOptions[last_option].current_item
KOPTOptions[last_option].marker_dirty[last_option_item] = true
current_option_item = KOPTOptions[self.current_option].current_item
KOPTOptions[self.current_option].marker_dirty[current_option_item] = true
end
)
self.commands:add(KEY_FW_UP, nil, "joypad up",
"previous item",
function(self)
local last_option = self.current_option
self.current_option = (self.current_option + #KOPTOptions - 1)%#KOPTOptions
self.current_option = (self.current_option == 0) and #KOPTOptions or self.current_option
last_option_item = KOPTOptions[last_option].current_item
KOPTOptions[last_option].marker_dirty[last_option_item] = true
current_option_item = KOPTOptions[self.current_option].current_item
KOPTOptions[self.current_option].marker_dirty[current_option_item] = true
end
)
self.commands:add(KEY_FW_LEFT, nil, "joypad left",
"last item",
function(self)
local last_item = KOPTOptions[self.current_option].current_item
local item_count = #KOPTOptions[self.current_option].items_text
local current_item = (KOPTOptions[self.current_option].current_item + item_count - 1)%item_count
current_item = (current_item == 0) and item_count or current_item
KOPTOptions[self.current_option].current_item = current_item
KOPTOptions[self.current_option].marker_dirty[last_item] = true
KOPTOptions[self.current_option].marker_dirty[current_item] = true
self.page_dirty = true
end
)
self.commands:add(KEY_FW_RIGHT, nil, "joypad right",
"next item",
function(self)
local last_item = KOPTOptions[self.current_option].current_item
local item_count = #KOPTOptions[self.current_option].items_text
local current_item = (KOPTOptions[self.current_option].current_item + item_count + 1)%item_count
current_item = (current_item == 0) and item_count or current_item
KOPTOptions[self.current_option].current_item = current_item
KOPTOptions[self.current_option].marker_dirty[last_item] = true
KOPTOptions[self.current_option].marker_dirty[current_item] = true
self.page_dirty = true
end
)
self.commands:add({KEY_F,KEY_AA,KEY_BACK}, nil, "Back",
"back",
function(self)
return "break"
end
)
end

@ -1,5 +1,15 @@
require "unireader"
require "inputbox"
require "koptconfig"
konfig = {
width = G_width,
height = G_height,
font_size = 1.0,
page_margin = 0.06,
line_spacing = 1.2,
word_spacing = 0.375,
}
KOPTReader = UniReader:new{}
@ -56,7 +66,7 @@ function KOPTReader:drawOrCache(no, preCache)
-- ideally, this should be factored out and only be called when needed (TODO)
local ok, page = pcall(self.doc.openPage, self.doc, no)
local width, height = G_width, G_height
local width, height = fb.bb:getWidth(), fb.bb:getHeight()
if not ok then
-- TODO: error handling
return nil
@ -65,7 +75,7 @@ function KOPTReader:drawOrCache(no, preCache)
local dc = self:setzoom(page, preCache)
-- check if we have relevant cache contents
local pagehash = no..'_'..self.kopt_zoom..'_'..self.globalrotate..'_'..self.kopt_gamma..'K'
local pagehash = no..'_'..self.kopt_zoom..'_'..self.globalrotate..'_'..self.kopt_gamma..'_'..konfig.line_spacing..'_'..konfig.word_spacing..'K'
Debug('page hash', pagehash)
if self.cache[pagehash] ~= nil then
-- we have something in cache
@ -122,9 +132,10 @@ function KOPTReader:drawOrCache(no, preCache)
max_cache = max_cache - self.cache[self.pagehash].size
end
self.fullwidth, self.fullheight, self.kopt_zoom = page:reflow(dc, self.render_mode)
Debug("page::reflowPage:", "width:", width, "height:", height)
self.fullwidth, self.fullheight, self.kopt_zoom = page:reflow(dc, self.render_mode, width, height, konfig.line_spacing, konfig.word_spacing)
self.globalzoom_orig = self.kopt_zoom
Debug("page::reflowPage:", "width:", self.fullwidth, "height:", self.fullheight, "zoom:", self.kopt_zoom)
Debug("page::reflowPage:", "fullwidth:", self.fullwidth, "fullheight:", self.fullheight, "zoom:", self.kopt_zoom)
if (self.fullwidth * self.fullheight / 2) <= max_cache then
-- yes we can, so do this with offset 0, 0
@ -283,6 +294,14 @@ function KOPTReader:init()
self:adjustCommands()
end
function KOPTReader:reconfigure(configurable)
konfig.font_size = configurable.font_size
konfig.page_margin = configurable.page_margin
konfig.line_spacing = configurable.line_spacing
konfig.word_spacing = configurable.word_spacing
self:redrawCurrentPage()
end
function KOPTReader:adjustCommands()
self.commands:del(KEY_A, nil,"A")
self.commands:del(KEY_A, MOD_SHIFT, "A")
@ -302,4 +321,11 @@ function KOPTReader:adjustCommands()
self.commands:del(KEY_L, nil, "L")
self.commands:del(KEY_L, MOD_SHIFT, "L")
self.commands:del(KEY_M, nil, "M")
self.commands:add({KEY_F,KEY_AA}, nil, "F",
"change koptreader configuration",
function(self)
KOPTConfig:config(KOPTReader.reconfigure, self)
self:redrawCurrentPage()
end
)
end

@ -515,9 +515,14 @@ static int reflowPage(lua_State *L) {
PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage");
DrawContext *dc = (DrawContext*) luaL_checkudata(L, 2, "drawcontext");
int width = (int) luaL_checkint(L, 4); // framebuffer size
int height = (int) luaL_checkint(L, 5);
double line_spacing = luaL_checknumber(L, 6);
double word_spacing = luaL_checknumber(L, 7);
int width, height;
k2pdfopt_mupdf_reflow(page->doc->xref, page->page, page->doc->context, dc->zoom, dc->gamma, 0);
//printf("reflowPage width:%d height:%d\n", width, height);
k2pdfopt_mupdf_reflow(page->doc->xref, page->page, page->doc->context, dc->zoom, dc->gamma, 0.0, width, height, line_spacing, word_spacing);
k2pdfopt_rfbmp_size(&width, &height);
k2pdfopt_rfbmp_zoom(&dc->zoom);

Loading…
Cancel
Save