diff --git a/Makefile b/Makefile index 41ee1f11d..ca25b57c7 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,7 @@ lfs.o: $(LFSDIR)/src/lfs.c fetchthirdparty: -rm -Rf lua lua-5.1.4 -rm -Rf mupdf/thirdparty - test -d mupdf && (cd mupdf; git checkout .) + test -d mupdf && (cd mupdf; git checkout .) || echo warn: mupdf folder not found git submodule init git submodule update ln -sf kpvcrlib/crengine/cr3gui/data data @@ -155,10 +155,10 @@ cleanthirdparty: make -C $(LUADIR) clean make -C $(MUPDFDIR) clean #make -C $(CRENGINEDIR)/thirdparty/antiword clean - make -C $(CRENGINEDIR)/thirdparty/chmlib clean - make -C $(CRENGINEDIR)/thirdparty/libpng clean - make -C $(CRENGINEDIR)/crengine clean - make -C $(KPVCRLIGDIR) clean + test -d $(CRENGINEDIR)/thirdparty/chmlib && make -C $(CRENGINEDIR)/thirdparty/chmlib clean || echo warn: chmlib folder not found + test -d $(CRENGINEDIR)/thirdparty/libpng && (make -C $(CRENGINEDIR)/thirdparty/libpng clean) || echo warn: chmlib folder not found + test -d $(CRENGINEDIR)/crengine && (make -C $(CRENGINEDIR)/crengine clean) || echo warn: chmlib folder not found + test -d $(KPVCRLIGDIR) && (make -C $(KPVCRLIGDIR) clean) || echo warn: chmlib folder not found -rm -rf $(DJVUDIR)/build -rm -f $(MUPDFDIR)/fontdump.host -rm -f $(MUPDFDIR)/cmapdump.host @@ -175,7 +175,7 @@ $(MUPDFDIR)/cmapdump.host: $(MUPDFLIBS) $(THIRDPARTYLIBS): $(MUPDFDIR)/cmapdump.host $(MUPDFDIR)/fontdump.host # build only thirdparty libs, libfitz and pdf utils, which will care for libmupdf.a being built - CFLAGS="$(CFLAGS) -DNOBUILTINFONT" make -C mupdf CC="$(CC)" CMAPDUMP=cmapdump.host FONTDUMP=fontdump.host MUPDF= XPS_APPS= verbose=1 + CFLAGS="$(CFLAGS) -DNOBUILTINFONT" make -C mupdf CC="$(CC)" CMAPDUMP=cmapdump.host FONTDUMP=fontdump.host MUPDF= MU_APPS= BUSY_APP= XPS_APPS= verbose=1 $(DJVULIBS): -mkdir $(DJVUDIR)/build diff --git a/font.lua b/font.lua index cdf658956..d7e0be87f 100644 --- a/font.lua +++ b/font.lua @@ -38,6 +38,7 @@ Font = { function Font:getFace(font, size) +print("getFace: "..font.." size:"..size) if not font then -- default to content font font = self.cfont @@ -57,6 +58,7 @@ function Font:getFace(font, size) return nil end self.faces[font..size] = face +print("getFace, found: "..realname.." size:"..size) end return { size = size, ftface = face, hash = font..size } end diff --git a/helppage.lua b/helppage.lua index 5c7041bd3..c69eedc5b 100644 --- a/helppage.lua +++ b/helppage.lua @@ -48,8 +48,8 @@ function HelpPage:show(ypos, height, commands) end table.sort(self.commands,function(w1,w2) return w1.orderfont = fz_new_font_from_memory(ctx, data, len, 0, 1); /* RJW: "cannot load freetype font from memory" */ @@ -13,13 +13,13 @@ index 5e54e0b..38bd1d8 100644 + fontdesc->font = fz_new_font_from_file(ctx, data, 0, 1); + free(data); +#endif - + if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) fontdesc->flags |= PDF_FD_SYMBOLIC; @@ -199,8 +204,13 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, int mono, int if (!data) fz_throw(ctx, "cannot find substitute font"); - + +#ifndef NOBUILTINFONT fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0, 1); /* RJW: "cannot load freetype font from memory" */ @@ -27,12 +27,12 @@ index 5e54e0b..38bd1d8 100644 + fontdesc->font = fz_new_font_from_file(ctx, data, 0, 1); + free(data); +#endif - + fontdesc->font->ft_substitute = 1; fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face); @@ -218,7 +228,12 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, int ros, fz_throw(ctx, "cannot find builtin CJK font"); - + /* a glyph bbox cache is too big for droid sans fallback (51k glyphs!) */ +#ifndef NOBUILTINFONT fontdesc->font = fz_new_font_from_memory(ctx, data, len, 0, 0); @@ -41,7 +41,7 @@ index 5e54e0b..38bd1d8 100644 + free(data); +#endif /* RJW: "cannot load builtin CJK font" */ - + fontdesc->font->ft_substitute = 1; diff --git a/pdf/pdf_fontfile.c b/pdf/pdf_fontfile.c index 543ce76..a076033 100644 @@ -50,7 +50,7 @@ index 543ce76..a076033 100644 @@ -1,6 +1,8 @@ #include "fitz.h" #include "mupdf.h" - + +#ifndef NOBUILTINFONT + #ifdef NOCJK @@ -83,7 +83,7 @@ index 543ce76..a076033 100644 +} + +unsigned char * -+pdf_find_builtin_font(char *name, unsigned int *len) ++pdf_lookup_builtin_font(char *name, unsigned int *len) +{ + *len = 0; + if (!strcmp("Courier", name)) { @@ -132,37 +132,37 @@ index 543ce76..a076033 100644 +} + +unsigned char * -+pdf_find_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len) ++pdf_lookup_substitute_font(int mono, int serif, int bold, int italic, unsigned int *len) +{ + if (mono) { + if (bold) { -+ if (italic) return pdf_find_builtin_font("Courier-BoldOblique", len); -+ else return pdf_find_builtin_font("Courier-Bold", len); ++ if (italic) return pdf_lookup_builtin_font("Courier-BoldOblique", len); ++ else return pdf_lookup_builtin_font("Courier-Bold", len); + } else { -+ if (italic) return pdf_find_builtin_font("Courier-Oblique", len); -+ else return pdf_find_builtin_font("Courier", len); ++ if (italic) return pdf_lookup_builtin_font("Courier-Oblique", len); ++ else return pdf_lookup_builtin_font("Courier", len); + } + } else if (serif) { + if (bold) { -+ if (italic) return pdf_find_builtin_font("Times-BoldItalic", len); -+ else return pdf_find_builtin_font("Times-Bold", len); ++ if (italic) return pdf_lookup_builtin_font("Times-BoldItalic", len); ++ else return pdf_lookup_builtin_font("Times-Bold", len); + } else { -+ if (italic) return pdf_find_builtin_font("Times-Italic", len); -+ else return pdf_find_builtin_font("Times-Roman", len); ++ if (italic) return pdf_lookup_builtin_font("Times-Italic", len); ++ else return pdf_lookup_builtin_font("Times-Roman", len); + } + } else { + if (bold) { -+ if (italic) return pdf_find_builtin_font("Helvetica-BoldOblique", len); -+ else return pdf_find_builtin_font("Helvetica-Bold", len); ++ if (italic) return pdf_lookup_builtin_font("Helvetica-BoldOblique", len); ++ else return pdf_lookup_builtin_font("Helvetica-Bold", len); + } else { -+ if (italic) return pdf_find_builtin_font("Helvetica-Oblique", len); -+ else return pdf_find_builtin_font("Helvetica", len); ++ if (italic) return pdf_lookup_builtin_font("Helvetica-Oblique", len); ++ else return pdf_lookup_builtin_font("Helvetica", len); + } + } +} + +unsigned char * -+pdf_find_substitute_cjk_font(int ros, int serif, unsigned int *len) ++pdf_lookup_substitute_cjk_font(int ros, int serif, unsigned int *len) +{ + *len = 0; + return get_font_file("droid/DroidSansFallback.ttf"); diff --git a/mupdfimg.c b/mupdfimg.c index cdabaafca..8d745e4a2 100644 --- a/mupdfimg.c +++ b/mupdfimg.c @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include +#include #include "blitbuffer.h" #include "mupdfimg.h" diff --git a/pdf.c b/pdf.c index b47ea8926..9b89dcc3c 100644 --- a/pdf.c +++ b/pdf.c @@ -311,8 +311,105 @@ static int openPage(lua_State *L) { return 1; } +static void load_lua_text_page(lua_State *L, fz_text_page *page) +{ + fz_text_block *block; + fz_text_line *aline; + fz_text_span *span; + + fz_rect bbox, linebbox; + int i; + int word, line; + int len, c; + int start; + char chars[4]; // max length of UTF-8 encoded rune + luaL_Buffer textbuf; + + /* table that contains all the lines */ + lua_newtable(L); + for (block = page->blocks; block < page->blocks + page->len; block++) + { + for (aline = block->lines; aline < block->lines + block->len; aline++) + { + for (span = aline->spans; span < aline->spans + aline->len; span++) + { + linebbox = span->text[0].bbox; // start with sensible default + for(i = 0; i < span->len; ) { + /* will hold information about a word: */ + lua_newtable(L); + + luaL_buffinit(L, &textbuf); + bbox = span->text[i].bbox; // start with sensible default + for(; i < span->len; i++) { + /* check for space characters */ + if(span->text[i].c == ' ' || + span->text[i].c == '\t' || + span->text[i].c == '\n' || + span->text[i].c == '\v' || + span->text[i].c == '\f' || + span->text[i].c == '\r' || + span->text[i].c == 0xA0 || + span->text[i].c == 0x1680 || + span->text[i].c == 0x180E || + (span->text[i].c >= 0x2000 && span->text[i].c <= 0x200A) || + span->text[i].c == 0x202F || + span->text[i].c == 0x205F || + span->text[i].c == 0x3000) { + // ignore and end word + i++; + break; + } + len = fz_runetochar(chars, &span->text[i].c); + for(c = 0; c < len; c++) { + luaL_addchar(&textbuf, chars[c]); + } + bbox = fz_union_rect(bbox, span->text[i].bbox); + linebbox = fz_union_rect(linebbox, span->text[i].bbox); + } + lua_pushstring(L, "word"); + luaL_pushresult(&textbuf); + lua_settable(L, -3); + + /* bbox for a word: */ + lua_pushstring(L, "x0"); + lua_pushinteger(L, bbox.x0); + lua_settable(L, -3); + lua_pushstring(L, "y0"); + lua_pushinteger(L, bbox.y0); + lua_settable(L, -3); + lua_pushstring(L, "x1"); + lua_pushinteger(L, bbox.x1); + lua_settable(L, -3); + lua_pushstring(L, "y1"); + lua_pushinteger(L, bbox.y1); + lua_settable(L, -3); + + lua_rawseti(L, -2, word++); + } + + /* bbox for a whole line (or in fact, a "span") */ + lua_pushstring(L, "x0"); + lua_pushinteger(L, linebbox.x0); + lua_settable(L, -3); + lua_pushstring(L, "y0"); + lua_pushinteger(L, linebbox.y0); + lua_settable(L, -3); + lua_pushstring(L, "x1"); + lua_pushinteger(L, linebbox.x1); + lua_settable(L, -3); + lua_pushstring(L, "y1"); + lua_pushinteger(L, linebbox.y1); + lua_settable(L, -3); + + lua_rawseti(L, -2, line++); + + } + } + } +} + /* get the text of the given page - * + * * will return text in a Lua table that is modeled after * djvu.c creates this table. * @@ -327,105 +424,20 @@ static int openPage(lua_State *L) { * will return an empty table if we have no text */ static int getPageText(lua_State *L) { - fz_text_span *page_text; - fz_text_span *ptr; + fz_text_page *text_page; fz_device *tdev; - fz_bbox bbox, linebbox; - int i; - int word, line; - int len, c; - int start; - char chars[4]; // max length of UTF-8 encoded rune - luaL_Buffer textbuf; PdfPage *page = (PdfPage*) luaL_checkudata(L, 1, "pdfpage"); - page_text = fz_new_text_span(page->doc->context); - tdev = fz_new_text_device(page->doc->context, page_text); + text_page = fz_new_text_page(page->doc->context, fz_bound_page(page->doc->xref, page->page)); + tdev = fz_new_text_device(page->doc->context, NULL, text_page); fz_run_page(page->doc->xref, page->page, tdev, fz_identity, NULL); fz_free_device(tdev); + tdev = NULL; - /* table that contains all the lines */ - lua_newtable(L); - line = 1; - for(ptr = page_text; ptr != NULL; ptr = ptr->next) { - if(ptr->text == NULL) continue; - - /* table for the words */ - lua_newtable(L); - word = 1; - linebbox = ptr->text[0].bbox; // start with sensible default - for(i = 0; i < ptr->len; ) { - /* will hold information about a word: */ - lua_newtable(L); - - luaL_buffinit(L, &textbuf); - bbox = ptr->text[i].bbox; // start with sensible default - for(; i < ptr->len; i++) { - /* check for space characters */ - if(ptr->text[i].c == ' ' || - ptr->text[i].c == '\t' || - ptr->text[i].c == '\n' || - ptr->text[i].c == '\v' || - ptr->text[i].c == '\f' || - ptr->text[i].c == '\r' || - ptr->text[i].c == 0xA0 || - ptr->text[i].c == 0x1680 || - ptr->text[i].c == 0x180E || - (ptr->text[i].c >= 0x2000 && ptr->text[i].c <= 0x200A) || - ptr->text[i].c == 0x202F || - ptr->text[i].c == 0x205F || - ptr->text[i].c == 0x3000) { - // ignore and end word - i++; - break; - } - len = runetochar(chars, &ptr->text[i].c); - for(c = 0; c < len; c++) { - luaL_addchar(&textbuf, chars[c]); - } - bbox = fz_union_bbox(bbox, ptr->text[i].bbox); - linebbox = fz_union_bbox(linebbox, ptr->text[i].bbox); - } - lua_pushstring(L, "word"); - luaL_pushresult(&textbuf); - lua_settable(L, -3); - - /* bbox for a word: */ - lua_pushstring(L, "x0"); - lua_pushinteger(L, bbox.x0); - lua_settable(L, -3); - lua_pushstring(L, "y0"); - lua_pushinteger(L, bbox.y0); - lua_settable(L, -3); - lua_pushstring(L, "x1"); - lua_pushinteger(L, bbox.x1); - lua_settable(L, -3); - lua_pushstring(L, "y1"); - lua_pushinteger(L, bbox.y1); - lua_settable(L, -3); - - lua_rawseti(L, -2, word++); - } - - /* bbox for a whole line (or in fact, a "span") */ - lua_pushstring(L, "x0"); - lua_pushinteger(L, linebbox.x0); - lua_settable(L, -3); - lua_pushstring(L, "y0"); - lua_pushinteger(L, linebbox.y0); - lua_settable(L, -3); - lua_pushstring(L, "x1"); - lua_pushinteger(L, linebbox.x1); - lua_settable(L, -3); - lua_pushstring(L, "y1"); - lua_pushinteger(L, linebbox.y1); - lua_settable(L, -3); - - lua_rawseti(L, -2, line++); - } + load_lua_text_page(L, text_page); - fz_free_text_span(page->doc->context, page_text); + fz_free_text_page(page->doc->context, text_page); return 1; } diff --git a/rendertext.lua b/rendertext.lua index 32dd2e084..320f7dd41 100644 --- a/rendertext.lua +++ b/rendertext.lua @@ -44,7 +44,7 @@ function clearGlyphCache() glyphcache = {} end -function sizeUtf8Text(x, width, face, facehash, text, kerning) +function sizeUtf8Text(x, width, face, text, kerning) if text == nil then print("# sizeUtf8Text called without text"); return @@ -59,13 +59,13 @@ function sizeUtf8Text(x, width, face, facehash, text, kerning) for uchar in string.gfind(text, "([%z\1-\127\194-\244][\128-\191]*)") do if pen_x < (width - x) then local charcode = util.utf8charcode(uchar) - local glyph = getGlyph(face, facehash, charcode) + local glyph = getGlyph(face, charcode) if kerning and prevcharcode then - local kern = face:getKerning(prevcharcode, charcode) + local kern = face.ftface:getKerning(prevcharcode, charcode) pen_x = pen_x + kern - print("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." kern:"..kern) + --print("prev:"..string.char(prevcharcode).." curr:"..string.char(charcode).." kern:"..kern) else - print("curr:"..string.char(charcode)) + --print("curr:"..string.char(charcode)) end pen_x = pen_x + glyph.ax pen_y_top = math.max(pen_y_top, glyph.t) @@ -77,10 +77,10 @@ function sizeUtf8Text(x, width, face, facehash, text, kerning) return { x = pen_x, y_top = pen_y_top, y_bottom = pen_y_bottom} end -function renderUtf8Text(buffer, x, y, face, facehash, text, kerning, backgroundColor) +function renderUtf8Text(buffer, x, y, face, text, kerning) if text == nil then print("# renderUtf8Text called without text"); - return + return 0 end -- may still need more adaptive pen placement when kerning, -- see: http://freetype.org/freetype2/docs/glyphs/glyphs-4.html