diff --git a/Makefile.defs b/Makefile.defs index 9316fb925..ad3eb21cb 100644 --- a/Makefile.defs +++ b/Makefile.defs @@ -427,9 +427,7 @@ MUPDF_BUILD_DIR=$(CURDIR)/$(THIRDPARTY_DIR)/mupdf/build/$(MACHINE) MUPDF_DIR=$(MUPDF_BUILD_DIR)/mupdf-prefix/src/mupdf MUPDF_LIB_DIR=$(MUPDF_DIR)/build/release MUPDF_LIB_STATIC=$(MUPDF_LIB_DIR)/libmupdf.a -MUPDF_JS_LIB_STATIC=$(MUPDF_LIB_DIR)/libmujs.a -MUPDF_THIRDPARTY_LIBS=$(MUPDF_LIB_DIR)/libopenjpeg.a \ - $(MUPDF_LIB_DIR)/libjbig2dec.a \ +MUPDF_THIRDPARTY_LIBS=$(MUPDF_LIB_DIR)/libmupdfthird.a \ $(AES_LIB) MUPDF_LIB=$(OUTPUT_DIR)/libs/libmupdf$(LIB_EXT) diff --git a/Makefile.third b/Makefile.third index f9ea9fd61..3e1ee71c0 100644 --- a/Makefile.third +++ b/Makefile.third @@ -66,7 +66,6 @@ $(MUPDF_LIB) $(MUPDF_DIR)/include: $(JPEG_LIB) \ -DAR="$(AR)" -DLDFLAGS="$(LDFLAGS) -L$(CURDIR)/$(OUTPUT_DIR)" \ -DXCFLAGS="$(CFLAGS) -DNOBUILTINFONT -I$(JPEG_DIR)/include -I$(FREETYPE_DIR)/include/freetype2 -I$(ZLIB_DIR) -I$(MINIZIP_DIR)" \ -DMUPDF_LIB_STATIC=$(MUPDF_LIB_STATIC) \ - -DMUPDF_JS_LIB_STATIC=$(MUPDF_JS_LIB_STATIC) \ -DMUPDF_THIRDPARTY_LIBS=$(MUPDF_THIRDPARTY_LIBS) \ -DMUPDF_LIB=$(CURDIR)/$(MUPDF_LIB) \ -DMUPDF_SONAME=$(notdir $(MUPDF_LIB)) \ diff --git a/blitbuffer.c b/blitbuffer.c index a19547ba4..8d86536af 100644 --- a/blitbuffer.c +++ b/blitbuffer.c @@ -599,8 +599,8 @@ void BB_add_blit_from(BlitBuffer *dst, BlitBuffer *src, int sbb_rotation = GET_BB_ROTATION(src); int dbb_rotation = GET_BB_ROTATION(dst); if (dbb_type != sbb_type) { - fprintf(stderr, "incompatible bb in file %s, line %d!\r\n", - __FILE__, __LINE__); exit(1); + fprintf(stderr, "incompatible bb (dst: %d, src: %d) in file %s, line %d!\r\n", + dbb_type, sbb_type, __FILE__, __LINE__); exit(1); } uint8_t r, g, b; uint8_t ainv = 0xFF - alpha; @@ -686,13 +686,9 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, int sbb_type = GET_BB_TYPE(src); int sbb_rotation = GET_BB_ROTATION(src); int dbb_rotation = GET_BB_ROTATION(dst); - if (dbb_type != sbb_type) { - fprintf(stderr, "incompatible bb in file %s, line %d!\r\n", - __FILE__, __LINE__); exit(1); - } uint8_t r, g, b, ainv, alpha; int d_x, d_y, o_x, o_y; - if (dbb_type == TYPE_BB8) { + if (dbb_type == TYPE_BB8 && sbb_type == TYPE_BB8) { o_x = offs_x; Color8 *dstptr, *srcptr; for (d_x = dest_x; d_x < dest_x + w; d_x++) { @@ -705,7 +701,7 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, } o_x += 1; } - } else if (dbb_type == TYPE_BB8A) { + } else if (dbb_type == TYPE_BB8A && sbb_type == TYPE_BB8A) { o_x = offs_x; Color8A *dstptr, *srcptr; for (d_x = dest_x; d_x < dest_x + w; d_x++) { @@ -720,7 +716,7 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, } o_x += 1; } - } else if (dbb_type == TYPE_BBRGB16) { + } else if (dbb_type == TYPE_BBRGB16 && sbb_type == TYPE_BBRGB16) { o_x = offs_x; ColorRGB16 *dstptr, *srcptr; for (d_x = dest_x; d_x < dest_x + w; d_x++) { @@ -733,7 +729,7 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, } o_x += 1; } - } else if (dbb_type == TYPE_BBRGB24) { + } else if (dbb_type == TYPE_BBRGB24 && sbb_type == TYPE_BBRGB24) { o_x = offs_x; ColorRGB24 *dstptr, *srcptr; for (d_x = dest_x; d_x < dest_x + w; d_x++) { @@ -746,7 +742,7 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, } o_x += 1; } - } else if (dbb_type == TYPE_BBRGB32) { + } else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB32) { o_x = offs_x; ColorRGB32 *dstptr, *srcptr; for (d_x = dest_x; d_x < dest_x + w; d_x++) { @@ -763,6 +759,25 @@ void BB_alpha_blit_from(BlitBuffer *dst, BlitBuffer *src, } o_x += 1; } + } else if (dbb_type == TYPE_BBRGB32 && sbb_type == TYPE_BBRGB24) { + o_x = offs_x; + ColorRGB32 *dstptr; + ColorRGB24 *srcptr; + for (d_x = dest_x; d_x < dest_x + w; d_x++) { + o_y = offs_y; + for (d_y = dest_y; d_y < dest_y + h; d_y++) { + BB_GET_PIXEL(dst, dbb_rotation, ColorRGB32, d_x, d_y, &dstptr); + BB_GET_PIXEL(src, sbb_rotation, ColorRGB24, o_x, o_y, &srcptr); + dstptr->r = srcptr->r; + dstptr->g = srcptr->g; + dstptr->b = srcptr->b; + o_y += 1; + } + o_x += 1; + } + } else { + fprintf(stderr, "incompatible bb (dst: %d, src: %d) in file %s, line %d!\r\n", + dbb_type, sbb_type, __FILE__, __LINE__); exit(1); } } @@ -773,8 +788,8 @@ void BB_invert_blit_from(BlitBuffer *dst, BlitBuffer *src, int sbb_rotation = GET_BB_ROTATION(src); int dbb_rotation = GET_BB_ROTATION(dst); if (dbb_type != sbb_type) { - fprintf(stderr, "incompatible bb in file %s, line %d!\r\n", - __FILE__, __LINE__); exit(1); + fprintf(stderr, "incompatible bb (dst: %d, src: %d) in file %s, line %d!\r\n", + dbb_type, sbb_type, __FILE__, __LINE__); exit(1); } int d_x, d_y, o_x, o_y; if (dbb_type == TYPE_BB8) { diff --git a/ffi-cdecl/mupdf_decl.c b/ffi-cdecl/mupdf_decl.c index 53ee391e3..d33b9a4ca 100644 --- a/ffi-cdecl/mupdf_decl.c +++ b/ffi-cdecl/mupdf_decl.c @@ -3,7 +3,7 @@ #include "ffi-cdecl.h" -cdecl_const(FZ_PAGE_BLOCK_TEXT) +cdecl_const(FZ_STEXT_BLOCK_TEXT) /* math */ cdecl_type(fz_point) @@ -41,9 +41,17 @@ cdecl_func(fz_transform_rect) /* misc/assorted */ cdecl_type(fz_context) +cdecl_type(fz_font) +cdecl_type(fz_hash_table) cdecl_type(fz_storable) +cdecl_type(fz_key_storable) cdecl_type(fz_store_drop_fn) cdecl_struct(fz_storable_s) +cdecl_struct(fz_key_storable_s) + +/* buffer */ +cdecl_func(mupdf_new_buffer_from_shared_data) +cdecl_func(mupdf_drop_buffer) /* context */ cdecl_type(fz_alloc_context) @@ -57,10 +65,9 @@ cdecl_type(fz_image) cdecl_type(fz_pixmap) cdecl_struct(fz_image_s) cdecl_struct(fz_pixmap_s) -cdecl_func(fz_new_image_from_data) // compat, use wrapper instead: -cdecl_func(mupdf_new_image_from_data) -cdecl_func(fz_new_pixmap_from_image) // compat, use wrapper instead: -cdecl_func(mupdf_new_pixmap_from_image) +cdecl_func(mupdf_new_image_from_buffer) +cdecl_func(mupdf_get_pixmap_from_image) +cdecl_func(mupdf_save_pixmap_as_png) cdecl_func(fz_keep_image) cdecl_func(fz_drop_image) @@ -68,16 +75,14 @@ cdecl_func(fz_load_png) cdecl_func(fz_runetochar) /* document */ -cdecl_enum(fz_link_kind_e) -cdecl_type(fz_link_dest) -cdecl_struct(fz_link_dest_s) +cdecl_type(fz_annot) +cdecl_struct(fz_annot_s) cdecl_type(fz_outline) cdecl_struct(fz_outline_s) cdecl_type(fz_document) cdecl_type(fz_page) -cdecl_type(fz_write_options) -cdecl_struct(fz_document_s) cdecl_type(fz_link) +cdecl_struct(fz_document_s) cdecl_struct(fz_page_s) cdecl_func(mupdf_open_document) @@ -86,6 +91,7 @@ cdecl_func(fz_authenticate_password) cdecl_func(fz_drop_document) // NOTE: libk2pdfopt uses old fz_free_document symbol cdecl_func(mupdf_count_pages) cdecl_func(fz_lookup_metadata) +cdecl_func(fz_resolve_link) /* page */ cdecl_func(mupdf_load_page) @@ -102,33 +108,20 @@ cdecl_func(mupdf_load_outline) cdecl_func(fz_drop_outline) // NOTE: libk2pdfopt uses old fz_free_outline symbol /* structured text */ -cdecl_type(fz_text_style) -cdecl_struct(fz_text_style_s) - -cdecl_type(fz_text_char) -cdecl_struct(fz_text_char_s) - -cdecl_type(fz_text_span) -cdecl_struct(fz_text_span_s) - -cdecl_type(fz_text_line) -cdecl_struct(fz_text_line_s) - -cdecl_type(fz_text_sheet) -cdecl_struct(fz_text_sheet_s) -cdecl_func(mupdf_new_text_sheet) -cdecl_func(fz_drop_text_sheet) // NOTE: libk2pdfopt uses old fz_free_text_sheet symbol +cdecl_type(fz_stext_char) +cdecl_struct(fz_stext_char_s) -cdecl_type(fz_text_page) -cdecl_type(fz_page_block) -cdecl_struct(fz_text_page_s) -cdecl_func(mupdf_new_text_page) -cdecl_func(fz_drop_text_page) // NOTE: libk2pdfopt uses old fz_free_text_page symbol -cdecl_type(fz_text_block) -cdecl_struct(fz_page_block_s) -cdecl_struct(fz_text_block_s) +cdecl_type(fz_stext_line) +cdecl_struct(fz_stext_line_s) -cdecl_func(fz_text_char_bbox) +cdecl_type(fz_stext_block) +cdecl_struct(fz_stext_block_s) +cdecl_type(fz_stext_options) +cdecl_struct(fz_stext_options_s) +cdecl_type(fz_stext_page) +cdecl_struct(fz_stext_page_s) +cdecl_func(mupdf_new_stext_page_from_page) +cdecl_func(fz_drop_stext_page) // NOTE: libk2pdfopt uses old fz_free_text_page symbol /* pixmaps */ cdecl_func(mupdf_new_pixmap) @@ -141,6 +134,7 @@ cdecl_func(fz_keep_pixmap) cdecl_func(fz_drop_pixmap) cdecl_func(fz_clear_pixmap_with_value) cdecl_func(fz_gamma_pixmap) +cdecl_func(fz_scale_pixmap) cdecl_func(fz_pixmap_width) cdecl_func(fz_pixmap_height) cdecl_func(fz_pixmap_components) @@ -154,28 +148,35 @@ cdecl_func(mupdf_new_draw_device) cdecl_func(mupdf_new_text_device) cdecl_func(mupdf_new_bbox_device) cdecl_func(mupdf_run_page) +cdecl_func(fz_close_device) cdecl_func(fz_drop_device) // NOTE: libk2pdfopt uses old fz_free_device symbol /* pdf specifics */ +cdecl_enum(fz_annot_type) cdecl_type(pdf_hotspot) cdecl_struct(pdf_hotspot_s) cdecl_type(pdf_lexbuf) cdecl_struct(pdf_lexbuf_s) cdecl_type(pdf_lexbuf_large) cdecl_struct(pdf_lexbuf_large_s) +cdecl_type(pdf_obj) +cdecl_type(pdf_xobject) cdecl_type(pdf_annot) cdecl_type(pdf_page) +cdecl_struct(pdf_xobject_s) cdecl_struct(pdf_annot_s) cdecl_type(pdf_document) cdecl_struct(pdf_document_s) cdecl_func(pdf_specifics) cdecl_func(mupdf_pdf_create_annot) -cdecl_func(mupdf_pdf_set_markup_annot_quadpoints) +cdecl_func(mupdf_pdf_set_annot_quad_points) +cdecl_func(mupdf_pdf_set_text_annot_position) cdecl_func(mupdf_pdf_set_markup_appearance) /* saving documents */ -cdecl_struct(fz_write_options_s) -cdecl_func(mupdf_write_document) +cdecl_type(pdf_write_options) +cdecl_struct(pdf_write_options_s) +cdecl_func(mupdf_pdf_save_document) /* the following is for our own wrapper lib: */ cdecl_func(mupdf_get_my_alloc_context) diff --git a/ffi/mupdf.lua b/ffi/mupdf.lua index 25f63fda2..628e29e54 100644 --- a/ffi/mupdf.lua +++ b/ffi/mupdf.lua @@ -33,7 +33,7 @@ local mupdf = { } -- this cannot get adapted by the cdecl file because it is a -- string constant. Must match the actual mupdf API: -local FZ_VERSION = "1.8" +local FZ_VERSION = "1.12.0" local document_mt = { __index = {} } local page_mt = { __index = {} } @@ -150,7 +150,7 @@ end local function toc_walker(toc, outline, depth) while outline ~= nil do table.insert(toc, { - page = outline.dest.ld.gotor.page + 1, + page = outline.page + 1, title = ffi.string(outline.title), depth = depth, }) @@ -247,20 +247,13 @@ end write the document to a new file --]] function document_mt.__index:writeDocument(filename) - -- the API takes a char*, not a const char*, - -- so we claim memory - and never free it. Too bad. - -- TODO: free on closing document? - local filename_str = ffi.C.malloc(#filename + 1) - if filename == nil then error("could not allocate memory for filename") end - ffi.copy(filename_str, filename) - local opts = ffi.new("fz_write_options[1]") + local opts = ffi.new("pdf_write_options[1]") opts[0].do_incremental = (filename == self.filename ) and 1 or 0 opts[0].do_ascii = 0 - opts[0].do_expand = 0 opts[0].do_garbage = 0 opts[0].do_linear = 0 opts[0].continue_on_error = 1 - local ok = W.mupdf_write_document(context(), self.doc, filename_str, opts) + local ok = W.mupdf_pdf_save_document(context(), ffi.cast("pdf_document*", self.doc), filename, opts) if ok == nil then merror("could not write document") end end @@ -307,6 +300,7 @@ function page_mt.__index:getUsedBBox() local dev = W.mupdf_new_bbox_device(context(), result) if dev == nil then merror("cannot allocate bbox_device") end local ok = W.mupdf_run_page(context(), self.page, dev, M.fz_identity, nil) + M.fz_close_device(context(), dev) M.fz_drop_device(context(), dev) if ok == nil then merror("cannot calculate bbox for page") end @@ -343,35 +337,37 @@ local function is_unicode_wspace(c) c == 0x3000 -- Ideographic space end local function is_unicode_bullet(c) - -- The last 2 aren't strictly bullets, but will do for our usage here + -- Not all of them are strictly bullets, but will do for our usage here return c == 0x2022 or -- Bullet c == 0x2023 or -- Triangular bullet + c == 0x25a0 or -- Black square + c == 0x25cb or -- White circle + c == 0x25cf or -- Black circle c == 0x25e6 or -- White bullet c == 0x2043 or -- Hyphen bullet c == 0x2219 or -- Bullet operator c == 149 or -- Ascii bullet c == C'*' end --- this function had (disabled) functionality to check for lines --- starting with a span that contained numbers, roman numbers or --- latin literals, optionally followed by ":" or ")" for which --- it would also return true. Since the implementation looked dubious --- and was disabled anyway, it was left out when porting to Lua/FFI API -local function is_list_entry(span) - local len = span.len - local text = span.text - for n = 0, len - 1 do - local c = text[n].c - if is_unicode_wspace(c) then - -- skip whitespace at the beginning - goto continue - elseif is_unicode_bullet(c) then - -- return true for all lines starting with bullets - return true - else - return false + +local function skip_starting_bullet(line) + local ch = line.first_char + local found_bullet = false + + while ch ~= nil do + if is_unicode_bullet(ch.c) then + found_bullet = true + elseif not is_unicode_wspace(ch.c) then + break end - ::continue:: + + ch = ch.next + end + + if found_bullet then + return ch + else + return line.first_char end end @@ -393,76 +389,59 @@ will return an empty table if we have no text --]] function page_mt.__index:getPageText() -- first, we run the page through a special device, the text_device - local text_page = W.mupdf_new_text_page(context()) + local text_page = W.mupdf_new_stext_page_from_page(context(), self.page, nil) if text_page == nil then merror("cannot alloc text_page") end - local text_sheet = W.mupdf_new_text_sheet(context()) - if text_sheet == nil then - M.fz_drop_text_page(context(), text_page) - merror("cannot alloc text_sheet") - end - local tdev = W.mupdf_new_text_device(context(), text_sheet, text_page) - if tdev == nil then - M.fz_drop_text_page(context(), text_page) - M.fz_drop_text_sheet(context(), text_sheet) - merror("cannot alloc text device") - end - - if W.mupdf_run_page(context(), self.page, tdev, M.fz_identity, nil) == nil then - M.fz_drop_text_page(context(), text_page) - M.fz_drop_text_sheet(context(), text_sheet) - M.fz_drop_device(context(), tdev) - merror("cannot run page through text device") - end -- now we analyze the data returned by the device and bring it -- into the format we want to return local lines = {} - local char_bbox = ffi.new("fz_rect[1]") - - for block_num = 0, text_page.len - 1 do - if text_page.blocks[block_num].type == M.FZ_PAGE_BLOCK_TEXT then - local block = text_page.blocks[block_num].u.text + local block = text_page.first_block + while block ~= nil do + if block.type == M.FZ_STEXT_BLOCK_TEXT then -- a block contains lines, which is our primary return datum - for line_num = 0, block.len - 1 do + local mupdf_line = block.u.t.first_line + while mupdf_line ~= nil do local line = {} local line_bbox = ffi.new("fz_rect[1]") - -- a line consists of spans, which can contain words - local span = block.lines[line_num].first_span - if span and is_list_entry(span) then - -- skip list bullets & co - span = span.next + local first_char = skip_starting_bullet( mupdf_line ) + local ch = first_char + local ch_len = 0 + while ch ~= nil do + ch = ch.next + ch_len = ch_len + 1 end - while span ~= nil do + + if ch_len > 0 then -- here we will collect UTF-8 chars before making them -- a Lua string: - local textbuf = ffi.new("char[?]", span.len * 4) + local textbuf = ffi.new("char[?]", ch_len * 4) - local i = 0 - while i < span.len do + ch = first_char + while ch ~= nil do local textlen = 0 local word_bbox = ffi.new("fz_rect[1]") - while i < span.len do - if is_unicode_wspace(span.text[i].c) then + while ch ~= nil do + if is_unicode_wspace(ch.c) then -- ignore and end word break end - textlen = textlen + M.fz_runetochar(textbuf + textlen, span.text[i].c) - M.fz_union_rect(word_bbox, M.fz_text_char_bbox(context(), char_bbox, span, i)) - M.fz_union_rect(line_bbox, char_bbox) - if span.text[i].c >= 0x4e00 and span.text[i].c <= 0x9FFF or -- CJK Unified Ideographs - span.text[i].c >= 0x2000 and span.text[i].c <= 0x206F or -- General Punctuation - span.text[i].c >= 0x3000 and span.text[i].c <= 0x303F or -- CJK Symbols and Punctuation - span.text[i].c >= 0x3400 and span.text[i].c <= 0x4DBF or -- CJK Unified Ideographs Extension A - span.text[i].c >= 0xF900 and span.text[i].c <= 0xFAFF or -- CJK Compatibility Ideographs - span.text[i].c >= 0xFF01 and span.text[i].c <= 0xFFEE or -- Halfwidth and Fullwidth Forms - span.text[i].c >= 0x20000 and span.text[i].c <= 0x2A6DF -- CJK Unified Ideographs Extension B + textlen = textlen + M.fz_runetochar(textbuf + textlen, ch.c) + M.fz_union_rect(word_bbox, ch.bbox) + M.fz_union_rect(line_bbox, ch.bbox) + if ch.c >= 0x4e00 and ch.c <= 0x9FFF or -- CJK Unified Ideographs + ch.c >= 0x2000 and ch.c <= 0x206F or -- General Punctuation + ch.c >= 0x3000 and ch.c <= 0x303F or -- CJK Symbols and Punctuation + ch.c >= 0x3400 and ch.c <= 0x4DBF or -- CJK Unified Ideographs Extension A + ch.c >= 0xF900 and ch.c <= 0xFAFF or -- CJK Compatibility Ideographs + ch.c >= 0xFF01 and ch.c <= 0xFFEE or -- Halfwidth and Fullwidth Forms + ch.c >= 0x20000 and ch.c <= 0x2A6DF -- CJK Unified Ideographs Extension B then -- end word break end - i = i + 1 + ch = ch.next end -- add word to line table.insert(line, { @@ -470,22 +449,28 @@ function page_mt.__index:getPageText() x0 = word_bbox[0].x0, y0 = word_bbox[0].y0, x1 = word_bbox[0].x1, y1 = word_bbox[0].y1, }) - i = i + 1 + + if ch == nil then + break + end + + ch = ch.next end - span = span.next - end - line.x0, line.y0 = line_bbox[0].x0, line_bbox[0].y0 - line.x1, line.y1 = line_bbox[0].x1, line_bbox[0].y1 + line.x0, line.y0 = line_bbox[0].x0, line_bbox[0].y0 + line.x1, line.y1 = line_bbox[0].x1, line_bbox[0].y1 - table.insert(lines, line) + table.insert(lines, line) + end + + mupdf_line = mupdf_line.next end end + + block = block.next end - M.fz_drop_device(context(), tdev) - M.fz_drop_text_sheet(context(), text_sheet) - M.fz_drop_text_page(context(), text_page) + M.fz_drop_stext_page(context(), text_page) return lines end @@ -506,12 +491,11 @@ function page_mt.__index:getPageLinks() x0 = link.rect.x0, y0 = link.rect.y0, x1 = link.rect.x1, y1 = link.rect.y1, } - if link.dest.kind == M.FZ_LINK_URI then - data.uri = ffi.string(link.dest.ld.uri.uri) - elseif link.dest.kind == M.FZ_LINK_GOTO then - data.page = link.dest.ld.gotor.page -- FIXME page+1? + local page = M.fz_resolve_link(context(), link.doc, link.uri, nil, nil) + if page >= 0 then + data.page = page -- FIXME page+1? else - mupdf.debug(string.format("ERROR: unknown link kind 0x%x", tonumber(link.dest.kind))) + data.uri = ffi.string(link.uri) end table.insert(links, data) link = link.next @@ -525,10 +509,11 @@ end local function run_page(page, pixmap, ctm) M.fz_clear_pixmap_with_value(context(), pixmap, 0xff) - local dev = W.mupdf_new_draw_device(context(), pixmap) + local dev = W.mupdf_new_draw_device(context(), nil, pixmap) if dev == nil then merror("cannot create draw device") end local ok = W.mupdf_run_page(context(), page.page, dev, ctm, nil) + M.fz_close_device(context(), dev) M.fz_drop_device(context(), dev) if ok == nil then merror("could not run page") end end @@ -566,7 +551,7 @@ function page_mt.__index:draw_new(draw_context, width, height, offset_x, offset_ local colorspace = mupdf.color and M.fz_device_rgb(context()) or M.fz_device_gray(context()) local pix = W.mupdf_new_pixmap_with_bbox_and_data( - context(), colorspace, bbox, ffi.cast("unsigned char*", bb.data)) + context(), colorspace, bbox, nil, 1, ffi.cast("unsigned char*", bb.data)) if pix == nil then merror("cannot allocate pixmap") end run_page(self, pix, ctm) @@ -590,18 +575,18 @@ function page_mt.__index:addMarkupAnnotation(points, n, type) local alpha = 1.0 local line_height = 0.5 local line_thickness = 1.0 - if type == M.FZ_ANNOT_HIGHLIGHT then + if type == M.PDF_ANNOT_HIGHLIGHT then color[0] = 1.0 color[1] = 1.0 color[2] = 0.0 alpha = 0.5 - elseif type == M.FZ_ANNOT_UNDERLINE then + elseif type == M.PDF_ANNOT_UNDERLINE then color[0] = 0.0 color[1] = 0.0 color[2] = 1.0 line_thickness = mupdf.LINE_THICKNESS line_height = mupdf.UNDERLINE_HEIGHT - elseif type == M.FZ_ANNOT_STRIKEOUT then + elseif type == M.PDF_ANNOT_STRIKEOUT then color[0] = 1.0 color[1] = 0.0 color[2] = 0.0 @@ -614,10 +599,10 @@ function page_mt.__index:addMarkupAnnotation(points, n, type) local doc = M.pdf_specifics(context(), self.doc.doc) if doc == nil then merror("could not get pdf_specifics") end - local annot = W.mupdf_pdf_create_annot(context(), doc, ffi.cast("pdf_page*", self.page), type) + local annot = W.mupdf_pdf_create_annot(context(), ffi.cast("pdf_page*", self.page), type) if annot == nil then merror("could not create annotation") end - local ok = W.mupdf_pdf_set_markup_annot_quadpoints(context(), doc, annot, points, n) + local ok = W.mupdf_pdf_set_annot_quad_points(context(), annot, n, points) if ok == nil then merror("could not set markup annot quadpoints") end ok = W.mupdf_pdf_set_markup_appearance(context(), doc, annot, color, alpha, line_thickness, line_height) @@ -631,20 +616,22 @@ end Renders image data. --]] function mupdf.renderImage(data, size, width, height) - local image = W.mupdf_new_image_from_data(context(), - ffi.cast("unsigned char*", data), size) + local buffer = W.mupdf_new_buffer_from_shared_data(context(), + ffi.cast("unsigned char*", data), size) + local image = W.mupdf_new_image_from_buffer(context(), buffer) + W.mupdf_drop_buffer(context(), buffer) if image == nil then merror("could not load image data") end M.fz_keep_image(context(), image) - local pixmap = W.mupdf_new_pixmap_from_image(context(), - image, width or -1, height or -1) + local pixmap = W.mupdf_get_pixmap_from_image(context(), + image, nil, nil, nil, nil) + M.fz_drop_image(context(), image) if pixmap == nil then - M.fz_drop_image(context(), image) merror("could not create pixmap from image") end local p_width = M.fz_pixmap_width(context(), pixmap) local p_height = M.fz_pixmap_height(context(), pixmap) - -- mupdf_new_pixmap_from_image() may not scale image to the + -- mupdf_get_pixmap_from_image() may not scale image to the -- width and height provided, so check and scale it if needed if width and height and (p_width ~= width or p_height ~= height) then local scaled_pixmap = M.fz_scale_pixmap(context(), pixmap, 0, 0, width, height, nil) @@ -655,14 +642,15 @@ function mupdf.renderImage(data, size, width, height) end local bbtype local ncomp = M.fz_pixmap_components(context(), pixmap) - if ncomp == 2 then bbtype = BlitBuffer.TYPE_BB8A + if ncomp == 1 then bbtype = BlitBuffer.TYPE_BB8 + elseif ncomp == 2 then bbtype = BlitBuffer.TYPE_BB8A + elseif ncomp == 3 then bbtype = BlitBuffer.TYPE_BBRGB24 elseif ncomp == 4 then bbtype = BlitBuffer.TYPE_BBRGB32 else error("unsupported number of color components") end local p = M.fz_pixmap_samples(context(), pixmap) local bb = BlitBuffer.new(p_width, p_height, bbtype, p):copy() M.fz_drop_pixmap(context(), pixmap) - M.fz_drop_image(context(), image) return bb end @@ -690,10 +678,13 @@ function mupdf.scaleBlitBuffer(bb, width, height) -- but the other types' bb.data give corrupted resulting pixmap. local colorspace local converted_bb + local stride if bbtype == BlitBuffer.TYPE_BB8A then colorspace = M.fz_device_gray(context()) + stride = orig_w * 2 elseif bbtype == BlitBuffer.TYPE_BBRGB32 then colorspace = M.fz_device_rgb(context()) + stride = orig_w * 4 else -- We need to convert the other types to one of the working -- types, and TYPE_BBRGB32 is the only one that works with @@ -704,11 +695,12 @@ function mupdf.scaleBlitBuffer(bb, width, height) converted_bb:blitFrom(bb, 0, 0, 0, 0, orig_w, orig_h) bb = converted_bb -- we don't free() the provided bb, but we'll have to free our converted_bb colorspace = M.fz_device_rgb(context()) + stride = orig_w * 4 end -- We can now create a pixmap from this bb of correct type -- whose bb.data is valid for mupdf local pixmap = W.mupdf_new_pixmap_with_data(context(), colorspace, - orig_w, orig_h, ffi.cast("unsigned char*", bb.data)) + orig_w, orig_h, nil, 1, stride, ffi.cast("unsigned char*", bb.data)) if pixmap == nil then if converted_bb then converted_bb:free() end -- free our home made bb merror("could not create pixmap from blitbuffer") @@ -805,7 +797,7 @@ local function render_for_kopt(bmp, page, scale, bounds) local colorspace = mupdf.color and M.fz_device_rgb(context()) or M.fz_device_gray(context()) - local pix = W.mupdf_new_pixmap_with_bbox(context(), colorspace, bbox) + local pix = W.mupdf_new_pixmap_with_bbox(context(), colorspace, bbox, nil, 1) if pix == nil then merror("could not allocate pixmap") end run_page(page, pix, ctm) diff --git a/ffi/mupdf_h.lua b/ffi/mupdf_h.lua index 9e4336c38..3986a44ed 100644 --- a/ffi/mupdf_h.lua +++ b/ffi/mupdf_h.lua @@ -1,7 +1,7 @@ local ffi = require("ffi") ffi.cdef[[ -static const int FZ_PAGE_BLOCK_TEXT = 0; +static const int FZ_STEXT_BLOCK_TEXT = 0; typedef struct fz_point_s fz_point; struct fz_point_s { float x; @@ -50,38 +50,50 @@ fz_matrix *fz_translate(fz_matrix *, float, float); fz_matrix *fz_pre_translate(fz_matrix *, float, float); fz_rect *fz_transform_rect(fz_rect *restrict, const fz_matrix *restrict); typedef struct fz_context_s fz_context; +typedef struct fz_font_s fz_font; +typedef struct fz_hash_table_s fz_hash_table; typedef struct fz_storable_s fz_storable; +typedef struct fz_key_storable_s fz_key_storable; typedef void fz_store_drop_fn(fz_context *, fz_storable *); struct fz_storable_s { int refs; fz_store_drop_fn *drop; }; +struct fz_key_storable_s { + fz_storable storable; + short int store_key_refs; +}; +struct fz_buffer_s *mupdf_new_buffer_from_shared_data(fz_context *, const unsigned char *, long unsigned int); +void *mupdf_drop_buffer(fz_context *, struct fz_buffer_s *); typedef struct fz_alloc_context_s fz_alloc_context; typedef struct fz_colorspace_s fz_colorspace; -fz_context *fz_new_context_imp(fz_alloc_context *, struct fz_locks_context_s *, unsigned int, const char *); +fz_context *fz_new_context_imp(const fz_alloc_context *, const struct fz_locks_context_s *, long unsigned int, const char *); void fz_drop_context(fz_context *); void fz_register_document_handlers(fz_context *); typedef struct fz_image_s fz_image; typedef struct fz_pixmap_s fz_pixmap; struct fz_image_s { - fz_storable storable; + fz_key_storable key_storable; int w; int h; - int n; - int bpc; + unsigned char n; + unsigned char bpc; + unsigned int imagemask : 1; + unsigned int interpolate : 1; + unsigned int use_colorkey : 1; + unsigned int use_decode : 1; + unsigned int invert_cmyk_jpeg : 1; + unsigned int decoded : 1; + unsigned int scalable : 1; fz_image *mask; + int xres; + int yres; fz_colorspace *colorspace; - fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, int, int, int *); + void (*drop_image)(fz_context *, fz_image *); + fz_pixmap *(*get_pixmap)(fz_context *, fz_image *, fz_irect *, int, int, int *); + long unsigned int (*get_size)(fz_context *, fz_image *); int colorkey[64]; float decode[64]; - int imagemask; - int interpolate; - int usecolorkey; - int xres; - int yres; - int invert_cmyk_jpeg; - struct fz_compressed_buffer_s *buffer; - fz_pixmap *tile; }; struct fz_pixmap_s { fz_storable storable; @@ -89,72 +101,51 @@ struct fz_pixmap_s { int y; int w; int h; - int n; - int interpolate; + unsigned char n; + unsigned char s; + unsigned char alpha; + unsigned char flags; + long int stride; + struct fz_separations_s *seps; int xres; int yres; fz_colorspace *colorspace; unsigned char *samples; - int free_samples; + fz_pixmap *underlying; }; -fz_image *fz_new_image_from_data(fz_context *, unsigned char *, int); -fz_image *mupdf_new_image_from_data(fz_context *, unsigned char *, int); -fz_pixmap *fz_new_pixmap_from_image(fz_context *, fz_image *, int, int); -fz_pixmap *mupdf_new_pixmap_from_image(fz_context *, fz_image *, int, int); +fz_image *mupdf_new_image_from_buffer(fz_context *, struct fz_buffer_s *); +fz_pixmap *mupdf_get_pixmap_from_image(fz_context *, fz_image *, const fz_irect *, fz_matrix *, int *, int *); +void *mupdf_save_pixmap_as_png(fz_context *, fz_pixmap *, const char *); fz_image *fz_keep_image(fz_context *, fz_image *); void fz_drop_image(fz_context *, fz_image *); -fz_pixmap *fz_load_png(fz_context *, unsigned char *, int); +fz_pixmap *fz_load_png(fz_context *, const unsigned char *, long unsigned int); int fz_runetochar(char *, int); -enum fz_link_kind_e { - FZ_LINK_NONE = 0, - FZ_LINK_GOTO = 1, - FZ_LINK_URI = 2, - FZ_LINK_LAUNCH = 3, - FZ_LINK_NAMED = 4, - FZ_LINK_GOTOR = 5, -}; -typedef struct fz_link_dest_s fz_link_dest; -struct fz_link_dest_s { - enum fz_link_kind_e kind; - union { - struct { - int page; - char *dest; - int flags; - fz_point lt; - fz_point rb; - char *file_spec; - int new_window; - } gotor; - struct { - char *uri; - int is_map; - } uri; - struct { - char *file_spec; - int new_window; - int is_uri; - } launch; - struct { - char *named; - } named; - } ld; +typedef struct fz_annot_s fz_annot; +struct fz_annot_s { + int refs; + void (*drop_annot)(fz_context *, fz_annot *); + fz_rect *(*bound_annot)(fz_context *, fz_annot *, fz_rect *); + void (*run_annot)(fz_context *, fz_annot *, struct fz_device_s *, const fz_matrix *, struct fz_cookie_s *); + fz_annot *(*next_annot)(fz_context *, fz_annot *); }; typedef struct fz_outline_s fz_outline; struct fz_outline_s { int refs; char *title; - fz_link_dest dest; + char *uri; + int page; + float x; + float y; fz_outline *next; fz_outline *down; int is_open; }; typedef struct fz_document_s fz_document; typedef struct fz_page_s fz_page; -typedef struct fz_write_options_s fz_write_options; +typedef struct fz_link_s fz_link; struct fz_document_s { int refs; - void (*close)(fz_context *, fz_document *); + void (*drop_document)(fz_context *, fz_document *); int (*needs_password)(fz_context *, fz_document *); int (*authenticate_password)(fz_context *, fz_document *, const char *); int (*has_permission)(fz_context *, fz_document *, enum { @@ -165,28 +156,28 @@ struct fz_document_s { }); fz_outline *(*load_outline)(fz_context *, fz_document *); void (*layout)(fz_context *, fz_document *, float, float, float); + long int (*make_bookmark)(fz_context *, fz_document *, int); + int (*lookup_bookmark)(fz_context *, fz_document *, long int); + int (*resolve_link)(fz_context *, fz_document *, const char *, float *, float *); int (*count_pages)(fz_context *, fz_document *); fz_page *(*load_page)(fz_context *, fz_document *, int); int (*lookup_metadata)(fz_context *, fz_document *, const char *, char *, int); - void (*write)(fz_context *, fz_document *, char *, fz_write_options *); + fz_colorspace *(*get_output_intent)(fz_context *, fz_document *); int did_layout; + int is_reflowable; }; -typedef struct fz_link_s fz_link; struct fz_page_s { int refs; - void (*drop_page_imp)(fz_context *, fz_page *); + void (*drop_page)(fz_context *, fz_page *); fz_rect *(*bound_page)(fz_context *, fz_page *, fz_rect *); void (*run_page_contents)(fz_context *, fz_page *, struct fz_device_s *, const fz_matrix *, struct fz_cookie_s *); fz_link *(*load_links)(fz_context *, fz_page *); - struct fz_annot_s *(*first_annot)(fz_context *, fz_page *); - struct fz_annot_s *(*next_annot)(fz_context *, fz_page *, struct fz_annot_s *); - fz_rect *(*bound_annot)(fz_context *, fz_page *, struct fz_annot_s *, fz_rect *); - void (*run_annot)(fz_context *, fz_page *, struct fz_annot_s *, struct fz_device_s *, const fz_matrix *, struct fz_cookie_s *); - struct fz_transition_s *(*page_presentation)(fz_context *, fz_page *, float *); + fz_annot *(*first_annot)(fz_context *, fz_page *); + struct fz_transition_s *(*page_presentation)(fz_context *, fz_page *, struct fz_transition_s *, float *); void (*control_separation)(fz_context *, fz_page *, int, int); int (*separation_disabled)(fz_context *, fz_page *, int); - int (*count_separations)(fz_context *, fz_page *); - const char *(*get_separation)(fz_context *, fz_page *, int, unsigned int *, unsigned int *); + struct fz_separations_s *(*separations)(fz_context *, fz_page *); + int (*overprint)(fz_context *, fz_page *); }; fz_document *mupdf_open_document(fz_context *, const char *); int fz_needs_password(fz_context *, fz_document *); @@ -194,123 +185,97 @@ int fz_authenticate_password(fz_context *, fz_document *, const char *); void fz_drop_document(fz_context *, fz_document *); int mupdf_count_pages(fz_context *, fz_document *); int fz_lookup_metadata(fz_context *, fz_document *, const char *, char *, int); +int fz_resolve_link(fz_context *, fz_document *, const char *, float *, float *); fz_page *mupdf_load_page(fz_context *, fz_document *, int); fz_rect *fz_bound_page(fz_context *, fz_page *, fz_rect *); void fz_drop_page(fz_context *, fz_page *); struct fz_link_s { int refs; - fz_rect rect; - fz_link_dest dest; fz_link *next; + fz_rect rect; + void *doc; + char *uri; }; fz_link *mupdf_load_links(fz_context *, fz_page *); void fz_drop_link(fz_context *, fz_link *); fz_outline *mupdf_load_outline(fz_context *, fz_document *); void fz_drop_outline(fz_context *, fz_outline *); -typedef struct fz_text_style_s fz_text_style; -struct fz_text_style_s { - fz_text_style *next; - int id; - struct fz_font_s *font; - float size; - int wmode; - int script; - float ascender; - float descender; -}; -typedef struct fz_text_char_s fz_text_char; -struct fz_text_char_s { - fz_point p; +typedef struct fz_stext_char_s fz_stext_char; +struct fz_stext_char_s { int c; - fz_text_style *style; -}; -typedef struct fz_text_span_s fz_text_span; -struct fz_text_span_s { - int len; - int cap; - fz_text_char *text; - fz_point min; - fz_point max; - int wmode; - fz_matrix transform; - float ascender_max; - float descender_min; + fz_point origin; fz_rect bbox; - float base_offset; - float spacing; - int column; - float column_width; - int align; - float indent; - fz_text_span *next; + float size; + fz_font *font; + fz_stext_char *next; }; -typedef struct fz_text_line_s fz_text_line; -struct fz_text_line_s { - fz_text_span *first_span; - fz_text_span *last_span; - float distance; +typedef struct fz_stext_line_s fz_stext_line; +struct fz_stext_line_s { + int wmode; + fz_point dir; fz_rect bbox; - void *region; -}; -typedef struct fz_text_sheet_s fz_text_sheet; -struct fz_text_sheet_s { - int maxid; - fz_text_style *style; + fz_stext_char *first_char; + fz_stext_char *last_char; + fz_stext_line *prev; + fz_stext_line *next; }; -fz_text_sheet *mupdf_new_text_sheet(fz_context *); -void fz_drop_text_sheet(fz_context *, fz_text_sheet *); -typedef struct fz_text_page_s fz_text_page; -typedef struct fz_page_block_s fz_page_block; -struct fz_text_page_s { - fz_rect mediabox; - int len; - int cap; - fz_page_block *blocks; - fz_text_page *next; -}; -fz_text_page *mupdf_new_text_page(fz_context *); -void fz_drop_text_page(fz_context *, fz_text_page *); -typedef struct fz_text_block_s fz_text_block; -struct fz_page_block_s { +typedef struct fz_stext_block_s fz_stext_block; +struct fz_stext_block_s { int type; + fz_rect bbox; union { - fz_text_block *text; - struct fz_image_block_s *image; + struct { + fz_stext_line *first_line; + fz_stext_line *last_line; + } t; + struct { + fz_matrix transform; + fz_image *image; + } i; } u; + fz_stext_block *prev; + fz_stext_block *next; }; -struct fz_text_block_s { - fz_rect bbox; - int len; - int cap; - fz_text_line *lines; +typedef struct fz_stext_options_s fz_stext_options; +struct fz_stext_options_s { + int flags; }; -fz_rect *fz_text_char_bbox(fz_context *, fz_rect *, fz_text_span *, int); -fz_pixmap *mupdf_new_pixmap(fz_context *, fz_colorspace *, int, int); -fz_pixmap *fz_new_pixmap(fz_context *, fz_colorspace *, int, int); -fz_pixmap *mupdf_new_pixmap_with_bbox(fz_context *, fz_colorspace *, const fz_irect *); -fz_pixmap *mupdf_new_pixmap_with_data(fz_context *, fz_colorspace *, int, int, unsigned char *); -fz_pixmap *mupdf_new_pixmap_with_bbox_and_data(fz_context *, fz_colorspace *, const fz_irect *, unsigned char *); -fz_pixmap *fz_scale_pixmap(fz_context *, fz_pixmap *, float, float, float, float, fz_irect *); -void fz_convert_pixmap(fz_context *, fz_pixmap *, fz_pixmap *); +typedef struct fz_stext_page_s fz_stext_page; +struct fz_stext_page_s { + struct fz_pool_s *pool; + fz_rect mediabox; + fz_stext_block *first_block; + fz_stext_block *last_block; +}; +fz_stext_page *mupdf_new_stext_page_from_page(fz_context *, fz_page *, const fz_stext_options *); +void fz_drop_stext_page(fz_context *, fz_stext_page *); +fz_pixmap *mupdf_new_pixmap(fz_context *, fz_colorspace *, int, int, struct fz_separations_s *, int); +fz_pixmap *fz_new_pixmap(fz_context *, fz_colorspace *, int, int, struct fz_separations_s *, int); +fz_pixmap *mupdf_new_pixmap_with_bbox(fz_context *, fz_colorspace *, const fz_irect *, struct fz_separations_s *, int); +fz_pixmap *mupdf_new_pixmap_with_data(fz_context *, fz_colorspace *, int, int, struct fz_separations_s *, int, int, unsigned char *); +fz_pixmap *mupdf_new_pixmap_with_bbox_and_data(fz_context *, fz_colorspace *, const fz_irect *, struct fz_separations_s *, int, unsigned char *); +fz_pixmap *fz_convert_pixmap(fz_context *, fz_pixmap *, fz_colorspace *, fz_colorspace *, struct fz_default_colorspaces_s *, const struct fz_color_params_s *, int); fz_pixmap *fz_keep_pixmap(fz_context *, fz_pixmap *); void fz_drop_pixmap(fz_context *, fz_pixmap *); void fz_clear_pixmap_with_value(fz_context *, fz_pixmap *, int); void fz_gamma_pixmap(fz_context *, fz_pixmap *, float); +fz_pixmap *fz_scale_pixmap(fz_context *, fz_pixmap *, float, float, float, float, fz_irect *); int fz_pixmap_width(fz_context *, fz_pixmap *); int fz_pixmap_height(fz_context *, fz_pixmap *); int fz_pixmap_components(fz_context *, fz_pixmap *); unsigned char *fz_pixmap_samples(fz_context *, fz_pixmap *); fz_colorspace *fz_device_gray(fz_context *); fz_colorspace *fz_device_rgb(fz_context *); -struct fz_device_s *mupdf_new_draw_device(fz_context *, fz_pixmap *); -struct fz_device_s *mupdf_new_text_device(fz_context *, fz_text_sheet *, fz_text_page *); +struct fz_device_s *mupdf_new_draw_device(fz_context *, const fz_matrix *, fz_pixmap *); +struct fz_device_s *mupdf_new_text_device(fz_context *, fz_stext_page *, const fz_stext_options *); struct fz_device_s *mupdf_new_bbox_device(fz_context *, fz_rect *); void *mupdf_run_page(fz_context *, fz_page *, struct fz_device_s *, const fz_matrix *, struct fz_cookie_s *); +void fz_close_device(fz_context *, struct fz_device_s *); void fz_drop_device(fz_context *, struct fz_device_s *); +enum fz_annot_type; typedef struct pdf_hotspot_s pdf_hotspot; struct pdf_hotspot_s { int num; - int gen; int state; }; typedef struct pdf_lexbuf_s pdf_lexbuf; @@ -318,7 +283,7 @@ struct pdf_lexbuf_s { int size; int base_size; int len; - int i; + long int i; float f; char *scratch; char buffer[256]; @@ -328,70 +293,78 @@ struct pdf_lexbuf_large_s { pdf_lexbuf base; char buffer[65280]; }; +typedef struct pdf_obj_s pdf_obj; +typedef struct pdf_xobject_s pdf_xobject; typedef struct pdf_annot_s pdf_annot; typedef struct pdf_page_s pdf_page; +struct pdf_xobject_s { + fz_storable storable; + pdf_obj *obj; + int iteration; +}; struct pdf_annot_s { + fz_annot super; pdf_page *page; - struct pdf_obj_s *obj; - fz_rect rect; - fz_rect pagerect; - struct pdf_xobject_s *ap; + pdf_obj *obj; + pdf_xobject *ap; int ap_iteration; - fz_matrix matrix; + int dirty; pdf_annot *next; - pdf_annot *next_changed; - int annot_type; - int widget_type; }; typedef struct pdf_document_s pdf_document; struct pdf_document_s { fz_document super; struct fz_stream_s *file; int version; - int startxref; - int file_size; + long int startxref; + long int file_size; struct pdf_crypt_s *crypt; struct pdf_ocg_descriptor_s *ocg; + struct pdf_portfolio_s *portfolio; pdf_hotspot hotspot; + fz_colorspace *oi; int max_xref_len; int num_xref_sections; + int saved_num_xref_sections; int num_incremental_sections; int xref_base; int disallow_new_increments; struct pdf_xref_s *xref_sections; + struct pdf_xref_s *saved_xref_sections; int *xref_index; int freeze_updates; int has_xref_streams; - int page_count; + int rev_page_count; + struct pdf_rev_page_map_s *rev_page_map; int repair_attempted; int file_reading_linearly; - int file_length; - struct pdf_obj_s *linear_obj; - struct pdf_obj_s **linear_page_refs; + long int file_length; + int linear_page_count; + pdf_obj *linear_obj; + pdf_obj **linear_page_refs; int linear_page1_obj_num; - int linear_pos; + long int linear_pos; int linear_page_num; int hint_object_offset; int hint_object_length; int hints_loaded; struct { int number; - int offset; - int index; + long int offset; + long int index; } *hint_page; int *hint_shared_ref; struct { int number; - int offset; + long int offset; } *hint_shared; int hint_obj_offsets_max; - int *hint_obj_offsets; + long int *hint_obj_offsets; int resources_localised; pdf_lexbuf_large lexbuf; pdf_annot *focus; - struct pdf_obj_s *focus_obj; + pdf_obj *focus_obj; struct pdf_js_s *js; - void (*drop_js)(struct pdf_js_s *); int recalculating; int dirty; void (*update_appearance)(fz_context *, pdf_document *, pdf_annot *); @@ -399,50 +372,63 @@ struct pdf_document_s { void *event_cb_data; int num_type3_fonts; int max_type3_fonts; - struct fz_font_s **type3_fonts; + fz_font **type3_fonts; + struct { + fz_hash_table *images; + fz_hash_table *fonts; + } resources; + int orphans_max; + int orphans_count; + pdf_obj **orphans; }; pdf_document *pdf_specifics(fz_context *, fz_document *); -pdf_annot *mupdf_pdf_create_annot(fz_context *, pdf_document *, pdf_page *, enum { - FZ_ANNOT_TEXT = 0, - FZ_ANNOT_LINK = 1, - FZ_ANNOT_FREETEXT = 2, - FZ_ANNOT_LINE = 3, - FZ_ANNOT_SQUARE = 4, - FZ_ANNOT_CIRCLE = 5, - FZ_ANNOT_POLYGON = 6, - FZ_ANNOT_POLYLINE = 7, - FZ_ANNOT_HIGHLIGHT = 8, - FZ_ANNOT_UNDERLINE = 9, - FZ_ANNOT_SQUIGGLY = 10, - FZ_ANNOT_STRIKEOUT = 11, - FZ_ANNOT_STAMP = 12, - FZ_ANNOT_CARET = 13, - FZ_ANNOT_INK = 14, - FZ_ANNOT_POPUP = 15, - FZ_ANNOT_FILEATTACHMENT = 16, - FZ_ANNOT_SOUND = 17, - FZ_ANNOT_MOVIE = 18, - FZ_ANNOT_WIDGET = 19, - FZ_ANNOT_SCREEN = 20, - FZ_ANNOT_PRINTERMARK = 21, - FZ_ANNOT_TRAPNET = 22, - FZ_ANNOT_WATERMARK = 23, - FZ_ANNOT_3D = 24, +pdf_annot *mupdf_pdf_create_annot(fz_context *, pdf_page *, enum { + PDF_ANNOT_TEXT = 0, + PDF_ANNOT_LINK = 1, + PDF_ANNOT_FREE_TEXT = 2, + PDF_ANNOT_LINE = 3, + PDF_ANNOT_SQUARE = 4, + PDF_ANNOT_CIRCLE = 5, + PDF_ANNOT_POLYGON = 6, + PDF_ANNOT_POLY_LINE = 7, + PDF_ANNOT_HIGHLIGHT = 8, + PDF_ANNOT_UNDERLINE = 9, + PDF_ANNOT_SQUIGGLY = 10, + PDF_ANNOT_STRIKE_OUT = 11, + PDF_ANNOT_STAMP = 12, + PDF_ANNOT_CARET = 13, + PDF_ANNOT_INK = 14, + PDF_ANNOT_POPUP = 15, + PDF_ANNOT_FILE_ATTACHMENT = 16, + PDF_ANNOT_SOUND = 17, + PDF_ANNOT_MOVIE = 18, + PDF_ANNOT_WIDGET = 19, + PDF_ANNOT_SCREEN = 20, + PDF_ANNOT_PRINTER_MARK = 21, + PDF_ANNOT_TRAP_NET = 22, + PDF_ANNOT_WATERMARK = 23, + PDF_ANNOT_3D = 24, + PDF_ANNOT_UNKNOWN = -1, }); -void *mupdf_pdf_set_markup_annot_quadpoints(fz_context *, pdf_document *, pdf_annot *, fz_point *, int); +void *mupdf_pdf_set_annot_quad_points(fz_context *, pdf_annot *, int, const float *); +void *mupdf_pdf_set_text_annot_position(fz_context *, pdf_annot *, fz_point); void *mupdf_pdf_set_markup_appearance(fz_context *, pdf_document *, pdf_annot *, float *, float, float, float); -struct fz_write_options_s { +typedef struct pdf_write_options_s pdf_write_options; +struct pdf_write_options_s { int do_incremental; + int do_pretty; int do_ascii; - int do_deflate; - int do_expand; + int do_compress; + int do_compress_images; + int do_compress_fonts; + int do_decompress; int do_garbage; int do_linear; int do_clean; int continue_on_error; int *errors; }; -void *mupdf_write_document(fz_context *, fz_document *, char *, fz_write_options *); +void *mupdf_pdf_save_document(fz_context *, pdf_document *, const char *, pdf_write_options *); fz_alloc_context *mupdf_get_my_alloc_context(); int mupdf_get_cache_size(); int mupdf_error_code(fz_context *); diff --git a/spec/unit/data/simple-out.pdf b/spec/unit/data/simple-out.pdf index 082c0c191..50689d10a 100644 Binary files a/spec/unit/data/simple-out.pdf and b/spec/unit/data/simple-out.pdf differ diff --git a/spec/unit/mupdf_spec.lua b/spec/unit/mupdf_spec.lua index dfcc78abe..ad4dc488b 100644 --- a/spec/unit/mupdf_spec.lua +++ b/spec/unit/mupdf_spec.lua @@ -121,12 +121,12 @@ describe("mupdf module", function() assert.is_not_nil(doc) local page = doc:openPage(1) assert.is_not_nil(page) - page:addMarkupAnnotation(ffi.new("fz_point[4]", { - { x = 70, y = 930 }, - { x = 510, y = 930 }, - { x = 510, y = 970 }, - { x = 70, y = 970 }}), - 4, ffi.C.FZ_ANNOT_HIGHLIGHT) + page:addMarkupAnnotation(ffi.new("float[8]", { + 70, 930, + 510, 930, + 510, 970, + 70, 970 }), + 1, ffi.C.PDF_ANNOT_HIGHLIGHT) page:close() doc:writeDocument(simple_pdf_out) local out_f = io.open(simple_pdf_out, "r") @@ -154,7 +154,7 @@ describe("mupdf module", function() assert.equals(math.floor(bbox[1]*1000), 56145) assert.equals(math.floor(bbox[2]*1000), 69233) assert.equals(math.floor(bbox[3]*1000), 144790) - assert.equals(math.floor(bbox[4]*1000), 103669) + assert.equals(math.floor(bbox[4]*1000), 106089) end) it("should get page text", function() local text = page:getPageText() diff --git a/thirdparty/mupdf/CMakeLists.txt b/thirdparty/mupdf/CMakeLists.txt index 36fc3376f..e179df3d5 100644 --- a/thirdparty/mupdf/CMakeLists.txt +++ b/thirdparty/mupdf/CMakeLists.txt @@ -24,7 +24,6 @@ set(STATIC_BUILD_CMD sh -c "${STATIC_BUILD_CMD} third libs") # we generate a dynamic library from the static library: assert_var_defined(CFLAGS) assert_var_defined(MUPDF_LIB_STATIC) -assert_var_defined(MUPDF_JS_LIB_STATIC) assert_var_defined(MUPDF_THIRDPARTY_LIBS) assert_var_defined(MUPDF_SONAME) assert_var_defined(ZLIB) @@ -36,17 +35,15 @@ assert_var_defined(RPATH) if($ENV{DARWIN}) set(LINK_OPTS "-Wl,-rpath,'${RPATH}'") set(LINK_OPTS "${LINK_OPTS} -Wl,-all_load ${MUPDF_LIB_STATIC}") - set(LINK_OPTS "${LINK_OPTS} -Wl,-all_load ${MUPDF_JS_LIB_STATIC}") set(LINK_OPTS "${LINK_OPTS} -Wl,-all_load ${MUPDF_THIRDPARTY_LIBS}") set(LINK_OPTS "${LINK_OPTS} -dynamiclib -undefined dynamic_lookup") set(LINK_OPTS "${LINK_OPTS} build/release/libjbig2dec.a") else() set(LINK_OPTS "-Wl,-E -Wl,-rpath,'${RPATH}'") set(LINK_OPTS "${LINK_OPTS} -Wl,--whole-archive ${MUPDF_LIB_STATIC}") - set(LINK_OPTS "${LINK_OPTS} -Wl,--whole-archive ${MUPDF_JS_LIB_STATIC}") set(LINK_OPTS "${LINK_OPTS} -Wl,--no-whole-archive ${MUPDF_THIRDPARTY_LIBS}") set(LINK_OPTS "${LINK_OPTS} -Wl,-soname=${MUPDF_SONAME}") - set(LINK_OPTS "${LINK_OPTS} build/release/libopenjpeg.a build/release/libmujs.a build/release/libjbig2dec.a") + set(LINK_OPTS "${LINK_OPTS} build/release/libmupdfthird.a") endif() set(SHARED_BUILD_STR "${CC} -shared ${CFLAGS} ${LINK_OPTS} ${AES_LIB} ${ZLIB} ${JPEG_LIB} ${FREETYPE_LIB} -o ${MUPDF_LIB} -lm") @@ -60,13 +57,20 @@ set(SHARED_BUILD_CMD sh -c "${SHARED_BUILD_STR}") set(PATCH_CMD1 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/external_fonts.patch || true") # add support for encryted zips set(PATCH_CMD2 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/encrypted_zip.patch || true") +# use libjpeg as a shared library +set(PATCH_CMD3 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/libjpeg_shared.patch || true") +# vec_dot fix (see https://github.com/ArtifexSoftware/mupdf/pull/5, needed for v1.12) +set(PATCH_CMD4 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/vec_dot.patch || true") +# needed for Android +set(PATCH_CMD5 sh -c "patch -N -p1 < ${CMAKE_CURRENT_SOURCE_DIR}/size_max.patch || true") # TODO: ignore shared git submodules built outside of mupdf by ourselves +# https://git.ghostscript.com/mupdf.git is slow, so we use the official mirror on GitHub ep_get_source_dir(SOURCE_DIR) ko_write_gitclone_script( GIT_CLONE_SCRIPT_FILENAME - https://gitlab.com/koreader/mupdf.git - c3a0d0fe7615ae201efd882dc961f3815a92a375 + https://github.com/ArtifexSoftware/mupdf.git + tags/1.12.0 ${SOURCE_DIR} ) @@ -75,7 +79,7 @@ ExternalProject_Add( ${PROJECT_NAME} DOWNLOAD_COMMAND ${CMAKE_COMMAND} -P ${GIT_CLONE_SCRIPT_FILENAME} BUILD_IN_SOURCE 1 - PATCH_COMMAND COMMAND ${PATCH_CMD1} COMMAND ${PATCH_CMD2} + PATCH_COMMAND COMMAND ${PATCH_CMD1} COMMAND ${PATCH_CMD2} COMMAND ${PATCH_CMD3} COMMAND ${PATCH_CMD4} COMMAND ${PATCH_CMD5} # skip configure CONFIGURE_COMMAND "" BUILD_COMMAND ${BUILD_CMD_GENERATE} COMMAND ${STATIC_BUILD_CMD} COMMAND ${SHARED_BUILD_CMD} diff --git a/thirdparty/mupdf/encrypted_zip.patch b/thirdparty/mupdf/encrypted_zip.patch index 22da47dea..62c1cdcd5 100644 --- a/thirdparty/mupdf/encrypted_zip.patch +++ b/thirdparty/mupdf/encrypted_zip.patch @@ -1,52 +1,56 @@ -diff --git a/include/mupdf/fitz/unzip.h b/include/mupdf/fitz/unzip.h -index b19ffbd..e94970d 100644 ---- a/include/mupdf/fitz/unzip.h -+++ b/include/mupdf/fitz/unzip.h -@@ -19,4 +19,7 @@ void fz_drop_archive(fz_context *ctx, fz_archive *ar); - int fz_count_archive_entries(fz_context *ctx, fz_archive *zip); - const char *fz_list_archive_entry(fz_context *ctx, fz_archive *zip, int idx); +diff --git a/include/mupdf/fitz/archive.h b/include/mupdf/fitz/archive.h +index c204b34f..4854c1ac 100644 +--- a/include/mupdf/fitz/archive.h ++++ b/include/mupdf/fitz/archive.h +@@ -178,6 +178,9 @@ fz_archive *fz_open_zip_archive(fz_context *ctx, const char *path); + */ + fz_archive *fz_open_zip_archive_with_stream(fz_context *ctx, fz_stream *file); +int fz_archive_needs_password(fz_context *ctx, fz_archive *zip); +int fz_archive_authenticate_password(fz_context *ctx, fz_archive *zip, const char *password); + - #endif + typedef struct fz_zip_writer_s fz_zip_writer; + + fz_zip_writer *fz_new_zip_writer(fz_context *ctx, const char *filename); diff --git a/source/cbz/mucbz.c b/source/cbz/mucbz.c -index 91f6e9d..f9b9676 100644 +index 2d357b6e..861a7902 100644 --- a/source/cbz/mucbz.c +++ b/source/cbz/mucbz.c -@@ -186,6 +186,18 @@ cbz_load_page(fz_context *ctx, cbz_document *doc, int number) - return page; +@@ -210,6 +210,20 @@ cbz_load_page(fz_context *ctx, fz_document *doc_, int number) + return (fz_page*)page; } +int -+cbz_needs_password(fz_context *ctx, cbz_document *doc) ++cbz_needs_password(fz_context *ctx, fz_document *doc_) +{ -+ return fz_archive_needs_password(ctx, doc->zip); ++ cbz_document *doc = (cbz_document*)doc_; ++ return fz_archive_needs_password(ctx, doc->arch); +} + +int -+cbz_authenticate_password(fz_context *ctx, cbz_document *doc, const char *pwd_utf8) ++cbz_authenticate_password(fz_context *ctx, fz_document *doc_, const char *password) +{ -+ return fz_archive_authenticate_password(ctx, doc->zip, pwd_utf8); ++ cbz_document *doc = (cbz_document*)doc_; ++ return fz_archive_authenticate_password(ctx, doc->arch, password); +} + static int - cbz_lookup_metadata(fz_context *ctx, cbz_document *doc, const char *key, char *buf, int size) + cbz_lookup_metadata(fz_context *ctx, fz_document *doc_, const char *key, char *buf, int size) { -@@ -200,6 +212,8 @@ cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) - cbz_document *doc = fz_new_document(ctx, sizeof *doc); +@@ -230,6 +244,8 @@ cbz_open_document_with_stream(fz_context *ctx, fz_stream *file) + doc->super.count_pages = cbz_count_pages; + doc->super.load_page = cbz_load_page; + doc->super.lookup_metadata = cbz_lookup_metadata; ++ doc->super.needs_password = cbz_needs_password; ++ doc->super.authenticate_password = cbz_authenticate_password; - doc->super.close = (fz_document_close_fn *)cbz_close_document; -+ doc->super.needs_password = (fz_document_needs_password_fn *)cbz_needs_password; -+ doc->super.authenticate_password = (fz_document_authenticate_password_fn *)cbz_authenticate_password; - doc->super.count_pages = (fz_document_count_pages_fn *)cbz_count_pages; - doc->super.load_page = (fz_document_load_page_fn *)cbz_load_page; - doc->super.lookup_metadata = (fz_document_lookup_metadata_fn *)cbz_lookup_metadata; + fz_try(ctx) + { diff --git a/source/fitz/unzip.c b/source/fitz/unzip.c -index b14705b..27b9bdf 100644 +index 4eb90dda..2fc60f70 100644 --- a/source/fitz/unzip.c +++ b/source/fitz/unzip.c -@@ -17,10 +17,32 @@ +@@ -20,6 +20,27 @@ #define ZIP_ENCRYPTED_FLAG 0x1 @@ -71,18 +75,21 @@ index b14705b..27b9bdf 100644 +#define SALT_LENGTH(mode) (4 * (mode & 3) + 4) +#define MAC_LENGTH(mode) (10) + - struct zip_entry + typedef struct zip_entry_s zip_entry; + typedef struct fz_zip_archive_s fz_zip_archive; + +@@ -27,6 +48,7 @@ struct zip_entry_s { char *name; int offset, csize, usize; + int crypted; }; - struct fz_archive_s -@@ -29,6 +51,15 @@ struct fz_archive_s - fz_stream *file; + struct fz_zip_archive_s +@@ -35,6 +57,15 @@ struct fz_zip_archive_s + int count; - struct zip_entry *table; + zip_entry *entries; + + int crypted; + char password[128]; @@ -94,16 +101,16 @@ index b14705b..27b9bdf 100644 + fcrypt_ctx aes_ctx; }; - static inline int zip_toupper(int c) -@@ -81,6 +112,7 @@ static void read_zip_dir_imp(fz_context *ctx, fz_archive *zip, int start_offset) - int offset, count; + static void *zalloc_zip(void *opaque, unsigned int items, unsigned int size) +@@ -64,6 +95,7 @@ static void read_zip_dir_imp(fz_context *ctx, fz_zip_archive *zip, int start_off int namesize, metasize, commentsize; - int i; + char *name; + size_t n; + int general; - fz_seek(ctx, file, start_offset, 0); + zip->count = 0; -@@ -155,11 +187,17 @@ static void read_zip_dir_imp(fz_context *ctx, fz_archive *zip, int start_offset) +@@ -136,7 +168,7 @@ static void read_zip_dir_imp(fz_context *ctx, fz_zip_archive *zip, int start_off (void) fz_read_int16_le(ctx, file); /* version made by */ (void) fz_read_int16_le(ctx, file); /* version to extract */ @@ -112,19 +119,23 @@ index b14705b..27b9bdf 100644 (void) fz_read_int16_le(ctx, file); /* method */ (void) fz_read_int16_le(ctx, file); /* last mod file time */ (void) fz_read_int16_le(ctx, file); /* last mod file date */ - (void) fz_read_int32_le(ctx, file); /* crc-32 */ +@@ -199,6 +231,13 @@ static void read_zip_dir_imp(fz_context *ctx, fz_zip_archive *zip, int start_off + zip->entries[zip->count].csize = csize; + zip->entries[zip->count].usize = usize; + + if (general & ZIP_ENCRYPTED_FLAG) { + zip->crypted = 1; -+ zip->table[i].crypted = 1; ++ zip->entries[zip->count].crypted = 1; + } else { -+ zip->table[i].crypted = 0; ++ zip->entries[zip->count].crypted = 0; + } - zip->table[i].csize = fz_read_int32_le(ctx, file); - zip->table[i].usize = fz_read_int32_le(ctx, file); - namesize = fz_read_int16_le(ctx, file); -@@ -245,6 +283,10 @@ static int read_zip_entry_header(fz_context *ctx, fz_archive *zip, struct zip_en ++ + zip->count++; + } + } +@@ -207,6 +246,10 @@ static int read_zip_entry_header(fz_context *ctx, fz_zip_archive *zip, zip_entry { - fz_stream *file = zip->file; + fz_stream *file = zip->super.file; int sig, general, method, namelength, extralength; + int i, headerid, datasize, crc32, modtime, chk; + @@ -133,7 +144,7 @@ index b14705b..27b9bdf 100644 fz_seek(ctx, file, ent->offset, 0); -@@ -253,20 +295,66 @@ static int read_zip_entry_header(fz_context *ctx, fz_archive *zip, struct zip_en +@@ -215,20 +258,67 @@ static int read_zip_entry_header(fz_context *ctx, fz_zip_archive *zip, zip_entry fz_throw(ctx, FZ_ERROR_GENERIC, "wrong zip local file signature (0x%x)", sig); (void) fz_read_int16_le(ctx, file); /* version */ @@ -156,6 +167,7 @@ index b14705b..27b9bdf 100644 - fz_seek(ctx, file, namelength + extralength, 1); + fz_seek(ctx, file, namelength, 1); ++ + if (general & ZIP_ENCRYPTED_FLAG) { + if (method == AES_METHOD) { + while (extralength > 0) { @@ -177,7 +189,7 @@ index b14705b..27b9bdf 100644 + saltlength = SALT_LENGTH(zip->aes_encryption_mode); + fz_read(ctx, file, saltvalue, saltlength); + fz_read(ctx, file, passverifyread, AES_PWVERIFYSIZE); -+ fcrypt_init(zip->aes_encryption_mode, zip->password, strlen(zip->password), ++ fcrypt_init(zip->aes_encryption_mode, (const unsigned char*)zip->password, strlen(zip->password), + saltvalue, passverifycalc, &zip->aes_ctx); + for (i = 0; i < AES_PWVERIFYSIZE; i++) { + if (passverifyread[i] != passverifycalc[i]) { @@ -208,47 +220,52 @@ index b14705b..27b9bdf 100644 return method; } -@@ -275,6 +363,9 @@ static fz_stream *open_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en - { - fz_stream *file = zip->file; - int method = read_zip_entry_header(ctx, zip, ent); +@@ -285,6 +375,9 @@ static fz_stream *open_zip_entry(fz_context *ctx, fz_archive *arch, const char * + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find named zip archive entry"); + + method = read_zip_entry_header(ctx, zip, ent); + if (method == AES_METHOD) { + method = zip->aes_compression_method; + } if (method == 0) return fz_open_null(ctx, file, ent->usize, fz_tell(ctx, file)); if (method == 8) -@@ -288,10 +379,14 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en +@@ -299,6 +392,7 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *arch, const char * fz_buffer *ubuf; unsigned char *cbuf; int method; + int i; z_stream z; int code; + int len; +@@ -309,6 +403,10 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *arch, const char * + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find named zip archive entry"); method = read_zip_entry_header(ctx, zip, ent); + if (method == AES_METHOD) { + method = zip->aes_compression_method; + } - ++ ubuf = fz_new_buffer(ctx, ent->usize + 1); /* +1 because many callers will add a terminating zero */ - ubuf->len = ent->usize; -@@ -301,6 +396,14 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en - fz_try(ctx) - { - fz_read(ctx, file, ubuf->data, ent->usize); + + if (method == 0) +@@ -318,6 +416,15 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *arch, const char * + ubuf->len = fz_read(ctx, file, ubuf->data, ent->usize); + if (ubuf->len < (size_t)ent->usize) + fz_warn(ctx, "premature end of data in stored zip archive entry"); ++ + if (ent->crypted) { + if (zip->aes_encryption_mode) { + fcrypt_decrypt(ubuf->data, ent->usize, &zip->aes_ctx); + } else { + for(i = 0; i < ent->usize; ++i) -+ ubuf->data[i] = zdecode(zip->keys,zip->pcrc_32_tab, ubuf->data[i]); ++ ubuf->data[i] = zdecode(zip->keys, zip->pcrc_32_tab, ubuf->data[i]); + } + } } fz_catch(ctx) { -@@ -317,6 +420,15 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en +@@ -333,6 +440,16 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *arch, const char * { fz_read(ctx, file, cbuf, ent->csize); @@ -261,42 +278,45 @@ index b14705b..27b9bdf 100644 + } + } + } - z.zalloc = (alloc_func) fz_malloc_array; - z.zfree = (free_func) fz_free; ++ + z.zalloc = zalloc_zip; + z.zfree = zfree_zip; z.opaque = ctx; -@@ -359,6 +471,25 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *zip, struct zip_en +@@ -379,6 +496,26 @@ static fz_buffer *read_zip_entry(fz_context *ctx, fz_archive *arch, const char * + fz_throw(ctx, FZ_ERROR_GENERIC, "unknown zip method: %d", method); } - int -+fz_archive_needs_password(fz_context *ctx, fz_archive *zip) ++int fz_archive_needs_password(fz_context *ctx, fz_archive *arch) +{ ++ fz_zip_archive *zip = (fz_zip_archive *) arch; + return zip->crypted; +} + -+int -+fz_archive_authenticate_password(fz_context *ctx, fz_archive *zip, const char *password) ++int fz_archive_authenticate_password(fz_context *ctx, fz_archive *arch, const char *password) +{ ++ fz_zip_archive *zip = (fz_zip_archive *) arch; + int i; ++ + fz_strlcpy(zip->password, password, sizeof zip->password); + for (i = 0; i < zip->count; ++i) { -+ if (zip->table[i].crypted) { -+ return read_zip_entry_header(ctx, zip, &zip->table[i]) != -1; ++ if (zip->entries[i].crypted) { ++ return read_zip_entry_header(ctx, zip, &zip->entries[i]) != -1; + } + } + return 1; +} + -+int - fz_has_archive_entry(fz_context *ctx, fz_archive *zip, const char *name) + static int has_zip_entry(fz_context *ctx, fz_archive *arch, const char *name) { - if (zip->directory) -@@ -489,6 +620,9 @@ fz_open_archive(fz_context *ctx, const char *filename) + fz_zip_archive *zip = (fz_zip_archive *) arch; +@@ -426,6 +563,10 @@ fz_open_zip_archive_with_stream(fz_context *ctx, fz_stream *file) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot recognize zip archive"); - fz_try(ctx) - zip = fz_open_archive_with_stream(ctx, file); -+ zip->aes_compression_method = 0; -+ zip->aes_encryption_mode = 0; -+ zip->aes_version = 0; - fz_always(ctx) - fz_drop_stream(ctx, file); - fz_catch(ctx) + zip = fz_new_derived_archive(ctx, file, fz_zip_archive); ++ zip->crypted = 0; ++ zip->aes_compression_method = 0; ++ zip->aes_encryption_mode = 0; ++ zip->aes_version = 0; + zip->super.format = "zip"; + zip->super.count_entries = count_zip_entries; + zip->super.list_entry = list_zip_entry; diff --git a/thirdparty/mupdf/external_fonts.patch b/thirdparty/mupdf/external_fonts.patch index 088607f39..5378536eb 100644 --- a/thirdparty/mupdf/external_fonts.patch +++ b/thirdparty/mupdf/external_fonts.patch @@ -1,67 +1,76 @@ -diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c -index 35e61f9..8c5ad86 100644 ---- a/source/pdf/pdf-font.c -+++ b/source/pdf/pdf-font.c -@@ -188,7 +188,12 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, - if (!data) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname); - -+#ifndef NOBUILTINFONT - fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); -+#else -+ fontdesc->font = fz_new_font_from_file(ctx, fontname, data, 0, 1); -+ free(data); -+#endif - } - - if (!strcmp(clean_name, "Symbol") || !strcmp(clean_name, "ZapfDingbats")) -@@ -212,7 +217,12 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontnam - if (!data) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find substitute font"); - -+#ifndef NOBUILTINFONT - fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); -+#else -+ fontdesc->font = fz_new_font_from_file(ctx, fontname, data, 0, 1); -+ free(data); +diff --git a/Makefile b/Makefile +index 114a6eb6..73880a64 100644 +--- a/Makefile ++++ b/Makefile +@@ -320,7 +320,6 @@ MUPDF_OBJ := \ + $(FITZ_OBJ) \ + $(PDF_OBJ) \ + $(CMAP_OBJ) \ +- $(FONT_OBJ) \ + $(JAVASCRIPT_OBJ) \ + $(XPS_OBJ) \ + $(SVG_OBJ) \ +diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h +index ef4cd74d..65bce17f 100644 +--- a/include/mupdf/fitz/font.h ++++ b/include/mupdf/fitz/font.h +@@ -624,4 +624,11 @@ void fz_hb_lock(fz_context *ctx); + */ + void fz_hb_unlock(fz_context *ctx); + ++#ifdef NOBUILTINFONT ++ ++char *fz_lookup_base14_font_from_file(fz_context *ctx, const char *name); ++char *fz_lookup_cjk_font_from_file(fz_context *ctx, int registry, int serif, int wmode); ++ +#endif - fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face); - fontdesc->font->ft_italic = italic && !ft_is_italic(fontdesc->font->ft_face); - } -@@ -235,7 +245,12 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fon - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font"); - - /* A glyph bbox cache is too big for CJK fonts. */ ++ + #endif +diff --git a/source/fitz/font.c b/source/fitz/font.c +index e197fa1b..8b74c624 100644 +--- a/source/fitz/font.c ++++ b/source/fitz/font.c +@@ -320,9 +320,15 @@ void fz_install_load_system_font_funcs(fz_context *ctx, + fz_load_system_cjk_font_fn *f_cjk, + fz_load_system_fallback_font_fn *f_back) + { +#ifndef NOBUILTINFONT - fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, index, 0); + ctx->font->load_font = f; + ctx->font->load_cjk_font = f_cjk; + ctx->font->load_fallback_font = f_back; +#else -+ fontdesc->font = fz_new_font_from_file(ctx, fontname, data, 0, 1); -+ free(data); ++ ctx->font->load_font = NULL; ++ ctx->font->load_cjk_font = NULL; ++ ctx->font->load_fallback_font = NULL; +#endif - } - - fontdesc->font->ft_substitute = 1; -diff --git a/source/pdf/pdf-fontfile.c b/source/pdf/pdf-fontfile.c -index 86b6682..4e062de 100644 ---- a/source/pdf/pdf-fontfile.c -+++ b/source/pdf/pdf-fontfile.c -@@ -11,6 +11,8 @@ - Set NOCJKFULL to embed a smaller CJK font without CJK Extension A support. - */ - + } + + fz_font *fz_load_system_font(fz_context *ctx, const char *name, int bold, int italic, int needs_exact_metrics) +diff --git a/source/fitz/noto.c b/source/fitz/noto.c +index f6951ba2..40188875 100644 +--- a/source/fitz/noto.c ++++ b/source/fitz/noto.c +@@ -1,8 +1,12 @@ + #include "mupdf/fitz.h" + #include "mupdf/ucdn.h" + ++#include ++#include + #include + +#ifndef NOBUILTINFONT + - #ifdef NOCJK - #define NOCJKFONT - #endif -@@ -136,3 +138,116 @@ pdf_lookup_substitute_cjk_font(fz_context *ctx, int ros, int serif, int wmode, u - return NULL; + /* + Base 14 PDF fonts from URW. + Noto fonts from Google. +@@ -367,3 +371,122 @@ fz_lookup_noto_emoji_font(fz_context *ctx, int *size) + return *size = 0, NULL; #endif } + +#else // NOBUILTINFONT + -+unsigned char * ++char * +get_font_file(char *name) +{ + char *fontdir; @@ -80,10 +89,16 @@ index 86b6682..4e062de 100644 + return filename; +} + -+unsigned char * -+pdf_lookup_builtin_font(fz_context *ctx, const char *name, unsigned int *len) ++const unsigned char * ++fz_lookup_base14_font(fz_context *ctx, const char *name, int *size) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++char * ++fz_lookup_base14_font_from_file(fz_context *ctx, const char *name) +{ -+ *len = 0; + if (!strcmp("Courier", name)) { + return get_font_file("urw/NimbusMono-Regular.cff"); + } @@ -129,45 +144,244 @@ index 86b6682..4e062de 100644 + return NULL; +} + -+unsigned char * -+pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int italic, unsigned int *len) ++const unsigned char * ++fz_lookup_builtin_font(fz_context *ctx, const char *name, int is_bold, int is_italic, int *size) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++const unsigned char * ++fz_lookup_cjk_font(fz_context *ctx, int registry, int serif, int wmode, int *size, int *index) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++char * ++fz_lookup_cjk_font_from_file(fz_context *ctx, int registry, int serif, int wmode) ++{ ++ return get_font_file("noto/NotoSansCJK-Regular.ttf"); ++} ++ ++const unsigned char * ++fz_lookup_noto_font(fz_context *ctx, int script, int language, int serif, int *size) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++const unsigned char * ++fz_lookup_noto_symbol_font(fz_context *ctx, int *size) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++const unsigned char * ++fz_lookup_noto_emoji_font(fz_context *ctx, int *size) ++{ ++ *size = 0; ++ return NULL; ++} ++ ++#endif +diff --git a/source/html/html-font.c b/source/html/html-font.c +index d319a462..bb59e0d6 100644 +--- a/source/html/html-font.c ++++ b/source/html/html-font.c +@@ -3,6 +3,37 @@ + + #include + ++char * ++html_lookup_substitute_font_from_file(fz_context *ctx, int mono, int serif, int bold, int italic) +{ + if (mono) { + if (bold) { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Courier-BoldOblique", len); -+ else return pdf_lookup_builtin_font(ctx, "Courier-Bold", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Courier-BoldOblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Courier-Bold"); + } else { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Courier-Oblique", len); -+ else return pdf_lookup_builtin_font(ctx, "Courier", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Courier-Oblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Courier"); + } + } else if (serif) { + if (bold) { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Times-BoldItalic", len); -+ else return pdf_lookup_builtin_font(ctx, "Times-Bold", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Times-BoldItalic"); ++ else return fz_lookup_base14_font_from_file(ctx, "Times-Bold"); + } else { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Times-Italic", len); -+ else return pdf_lookup_builtin_font(ctx, "Times-Roman", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Times-Italic"); ++ else return fz_lookup_base14_font_from_file(ctx, "Times-Roman"); + } + } else { + if (bold) { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Helvetica-BoldOblique", len); -+ else return pdf_lookup_builtin_font(ctx, "Helvetica-Bold", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Helvetica-BoldOblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Helvetica-Bold"); + } else { -+ if (italic) return pdf_lookup_builtin_font(ctx, "Helvetica-Oblique", len); -+ else return pdf_lookup_builtin_font(ctx, "Helvetica", len); ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Helvetica-Oblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Helvetica"); + } + } +} + -+unsigned char * -+pdf_lookup_substitute_cjk_font(fz_context *ctx, int ros, int serif, int wmode, unsigned int *len, int *index) ++ + static fz_font * + fz_load_html_default_font(fz_context *ctx, fz_html_font_set *set, const char *family, int is_bold, int is_italic) + { +@@ -13,6 +44,7 @@ fz_load_html_default_font(fz_context *ctx, fz_html_font_set *set, const char *fa + int idx = (is_mono ? 8 : is_sans ? 4 : 0) + is_bold * 2 + is_italic; + if (!set->fonts[idx]) + { ++#ifndef NOBUILTINFONT + const unsigned char *data; + int size; + +@@ -23,6 +55,13 @@ fz_load_html_default_font(fz_context *ctx, fz_html_font_set *set, const char *fa + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load html font: %s", real_family); + set->fonts[idx] = fz_new_font_from_memory(ctx, NULL, data, size, 0, 1); + fz_font_flags(set->fonts[idx])->is_serif = !is_sans; ++#else ++ char * filename = html_lookup_substitute_font_from_file(ctx, is_mono, !is_sans, is_bold, is_italic); ++ if (!filename) ++ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load html font"); ++ ++ set->fonts[idx] = fz_new_font_from_file(ctx, NULL, filename, 0, 1); ++#endif + } + return set->fonts[idx]; + } +diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c +index be69ce1c..a24b2122 100644 +--- a/source/pdf/pdf-font.c ++++ b/source/pdf/pdf-font.c +@@ -54,6 +54,8 @@ static const char *base_font_names[][10] = + { "ZapfDingbats", NULL } + }; + ++#ifndef NOBUILTINFONT ++ + const unsigned char * + pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int italic, int *len) + { +@@ -84,6 +86,47 @@ pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int i + } + } + ++#else ++ ++const unsigned char * ++pdf_lookup_substitute_font(fz_context *ctx, int mono, int serif, int bold, int italic, int* len) +{ + *len = 0; -+ return get_font_file("noto/NotoSansCJK-Regular.ttf"); ++ return NULL; +} + -+void pdf_install_load_system_font_funcs(fz_context *ctx) ++char * ++pdf_lookup_substitute_font_from_file(fz_context *ctx, int mono, int serif, int bold, int italic) +{ ++ if (mono) { ++ if (bold) { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Courier-BoldOblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Courier-Bold"); ++ } else { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Courier-Oblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Courier"); ++ } ++ } else if (serif) { ++ if (bold) { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Times-BoldItalic"); ++ else return fz_lookup_base14_font_from_file(ctx, "Times-Bold"); ++ } else { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Times-Italic"); ++ else return fz_lookup_base14_font_from_file(ctx, "Times-Roman"); ++ } ++ } else { ++ if (bold) { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Helvetica-BoldOblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Helvetica-Bold"); ++ } else { ++ if (italic) return fz_lookup_base14_font_from_file(ctx, "Helvetica-Oblique"); ++ else return fz_lookup_base14_font_from_file(ctx, "Helvetica"); ++ } ++ } +} + -+#endif // NOBUILTINFONT ++#endif ++ + static int is_dynalab(char *name) + { + if (strstr(name, "HuaTian")) +@@ -350,6 +393,7 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *font + fontdesc->font = fz_load_system_font(ctx, fontname, 0, 0, !has_descriptor); + if (!fontdesc->font) + { ++#ifndef NOBUILTINFONT + const unsigned char *data; + int len; + +@@ -358,6 +402,15 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *font + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname); + + fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); ++#else ++ char * filename = fz_lookup_base14_font_from_file(ctx, clean_name); ++ if (!filename) ++ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname); ++ ++ fontdesc->font = fz_new_font_from_file(ctx, fontname, filename, 0, 1); ++ free(filename); ++#endif ++ + fontdesc->font->flags.is_serif = !!strstr(clean_name, "Times"); + } + +@@ -375,6 +428,7 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *f + fontdesc->font = fz_load_system_font(ctx, fontname, bold, italic, 0); + if (!fontdesc->font) + { ++#ifndef NOBUILTINFONT + const unsigned char *data; + int len; + +@@ -383,6 +437,15 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, const char *f + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find substitute font"); + + fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); ++#else ++ char * filename = pdf_lookup_substitute_font_from_file(ctx, mono, serif, bold, italic); ++ if (!filename) ++ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find substitute font"); ++ ++ fontdesc->font = fz_new_font_from_file(ctx, fontname, filename, 0, 1); ++ free(filename); ++#endif ++ + fontdesc->font->flags.fake_bold = bold && !fontdesc->font->flags.is_bold; + fontdesc->font->flags.fake_italic = italic && !fontdesc->font->flags.is_italic; + +@@ -402,6 +465,8 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, const cha + fontdesc->font = fz_load_system_cjk_font(ctx, fontname, ros, serif); + if (!fontdesc->font) + { ++ /* A glyph bbox cache is too big for CJK fonts. */ ++#ifndef NOBUILTINFONT + const unsigned char *data; + int len; + int index; +@@ -410,8 +475,15 @@ pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, const cha + if (!data) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font"); + +- /* A glyph bbox cache is too big for CJK fonts. */ + fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, index, 0); ++#else ++ char * filename = fz_lookup_cjk_font_from_file(ctx, ros, serif, fontdesc->wmode); ++ if (!filename) ++ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font"); ++ ++ fontdesc->font = fz_new_font_from_file(ctx, fontname, filename, 0, 1); ++ free(filename); ++#endif + } + + fontdesc->font->flags.ft_substitute = 1; diff --git a/thirdparty/mupdf/libjpeg_shared.patch b/thirdparty/mupdf/libjpeg_shared.patch new file mode 100644 index 000000000..0d24c05d6 --- /dev/null +++ b/thirdparty/mupdf/libjpeg_shared.patch @@ -0,0 +1,28 @@ +diff --git a/Makefile b/Makefile +index 114a6eb6..818d4ce5 100644 +--- a/Makefile ++++ b/Makefile +@@ -334,7 +334,6 @@ THIRD_OBJ := \ + $(HARFBUZZ_OBJ) \ + $(JBIG2DEC_OBJ) \ + $(JPEGXR_OBJ) \ +- $(LIBJPEG_OBJ) \ + $(LURATECH_OBJ) \ + $(MUJS_OBJ) \ + $(OPENJPEG_OBJ) \ +diff --git a/Makethird b/Makethird +index fbc8b7f8..47b4ba1b 100644 +--- a/Makethird ++++ b/Makethird +@@ -459,9 +459,9 @@ $(LIBJPEG_OUT): + $(LIBJPEG_OUT)/%.o: $(LIBJPEG_DIR)/%.c | $(LIBJPEG_OUT) + $(CC_CMD) -Dmain=xxxmain + +-LIBJPEG_CFLAGS := -Iscripts/libjpeg -I$(LIBJPEG_DIR) ++LIBJPEG_CFLAGS := -Iscripts/libjpeg -I$(LIBJPEG_DIR) -DSHARE_JPEG=1 + else +-LIBJPEG_CFLAGS := $(SYS_LIBJPEG_CFLAGS) -DSHARE_JPEG ++LIBJPEG_CFLAGS := $(SYS_LIBJPEG_CFLAGS) -DSHARE_JPEG=1 + LIBJPEG_LIBS := $(SYS_LIBJPEG_LIBS) + endif + diff --git a/thirdparty/mupdf/size_max.patch b/thirdparty/mupdf/size_max.patch new file mode 100644 index 000000000..8b46c32ae --- /dev/null +++ b/thirdparty/mupdf/size_max.patch @@ -0,0 +1,12 @@ +diff --git a/source/fitz/memory.c b/source/fitz/memory.c +index 41543112..c7beb85c 100644 +--- a/source/fitz/memory.c ++++ b/source/fitz/memory.c +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + /* Enable FITZ_DEBUG_LOCKING_TIMES below if you want to check the times + * for which locks are held too. */ diff --git a/thirdparty/mupdf/vec_dot.patch b/thirdparty/mupdf/vec_dot.patch new file mode 100644 index 000000000..9c077de90 --- /dev/null +++ b/thirdparty/mupdf/vec_dot.patch @@ -0,0 +1,13 @@ +diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c +index cd657acc..40b203b3 100644 +--- a/source/fitz/stext-device.c ++++ b/source/fitz/stext-device.c +@@ -212,7 +212,7 @@ direction_from_bidi_class(int bidiclass, int curdir) + } + } + +-static int ++static float + vec_dot(const fz_point *a, const fz_point *b) + { + return a->x * b->x + a->y * b->y; diff --git a/wrap-mupdf.c b/wrap-mupdf.c index cec95e827..422ae3b29 100644 --- a/wrap-mupdf.c +++ b/wrap-mupdf.c @@ -17,8 +17,10 @@ */ #include +#include #include #include +#include #include "wrap-mupdf.h" static double LOG_TRESHOLD_PERC = 0.05; // 5% @@ -65,7 +67,7 @@ static void log_size(char *funcName){ } static void * -my_malloc_default(void *opaque, unsigned int size) +my_malloc_default(void *opaque, size_t size) { struct header * h = malloc(size + sizeof(header)); if (h == NULL) @@ -97,7 +99,7 @@ my_free_default(void *opaque, void *ptr) } static void * -my_realloc_default(void *opaque, void *old, unsigned int size) +my_realloc_default(void *opaque, void *old, size_t size) { void * newp; if (old==NULL) { //practically, it's a malloc diff --git a/wrap-mupdf.h b/wrap-mupdf.h index 4ed46e511..87ea3e155 100644 --- a/wrap-mupdf.h +++ b/wrap-mupdf.h @@ -69,53 +69,64 @@ MUPDF_WRAP(mupdf_load_outline, fz_outline*, NULL, MUPDF_WRAP(mupdf_load_page, fz_page*, NULL, ret = fz_load_page(ctx, doc, pageno), fz_document *doc, int pageno) -MUPDF_WRAP(mupdf_new_text_sheet, fz_text_sheet*, NULL, - ret = fz_new_text_sheet(ctx)) -MUPDF_WRAP(mupdf_new_text_page, fz_text_page*, NULL, - ret = fz_new_text_page(ctx)) +MUPDF_WRAP(mupdf_new_stext_page_from_page, fz_stext_page*, NULL, + ret = fz_new_stext_page_from_page(ctx, page, options), + fz_page *page, const fz_stext_options *options) MUPDF_WRAP(mupdf_new_text_device, fz_device*, NULL, - ret = fz_new_text_device(ctx, sheet, page), - fz_text_sheet *sheet, fz_text_page *page) + ret = fz_new_stext_device(ctx, page, options), + fz_stext_page *page, const fz_stext_options *options) MUPDF_WRAP(mupdf_new_bbox_device, fz_device*, NULL, ret = fz_new_bbox_device(ctx, rectp), fz_rect *rectp) MUPDF_WRAP(mupdf_new_draw_device, fz_device*, NULL, - ret = fz_new_draw_device(ctx, dest), - fz_pixmap *dest) + ret = fz_new_draw_device(ctx, transform, dest), + const fz_matrix *transform, fz_pixmap *dest) MUPDF_WRAP(mupdf_run_page, void*, NULL, { fz_run_page(ctx, page, dev, transform, cookie); ret = (void*) -1; }, fz_page *page, fz_device *dev, const fz_matrix *transform, fz_cookie *cookie) -MUPDF_WRAP(mupdf_write_document, void*, NULL, - { fz_write_document(ctx, doc, filename, opts); ret = (void*) -1; }, - fz_document *doc, char* filename, fz_write_options *opts) +MUPDF_WRAP(mupdf_pdf_save_document, void*, NULL, + { pdf_save_document(ctx, doc, filename, opts); ret = (void*) -1; }, + pdf_document *doc, const char *filename, pdf_write_options *opts) MUPDF_WRAP(mupdf_new_pixmap, fz_pixmap*, NULL, - ret = fz_new_pixmap(ctx, cs, w, h), - fz_colorspace *cs, int w, int h) + ret = fz_new_pixmap(ctx, cs, w, h, seps, alpha), + fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha) MUPDF_WRAP(mupdf_new_pixmap_with_bbox, fz_pixmap*, NULL, - ret = fz_new_pixmap_with_bbox(ctx, cs, bbox), - fz_colorspace *cs, const fz_irect *bbox) + ret = fz_new_pixmap_with_bbox(ctx, cs, bbox, seps, alpha), + fz_colorspace *cs, const fz_irect *bbox, fz_separations *seps, int alpha) MUPDF_WRAP(mupdf_new_pixmap_with_data, fz_pixmap*, NULL, - ret = fz_new_pixmap_with_data(ctx, cs, w, h, samples), - fz_colorspace *cs, int w, int h, unsigned char *samples) + ret = fz_new_pixmap_with_data(ctx, cs, w, h, seps, alpha, stride, samples), + fz_colorspace *cs, int w, int h, fz_separations *seps, int alpha, int stride, unsigned char *samples) MUPDF_WRAP(mupdf_new_pixmap_with_bbox_and_data, fz_pixmap*, NULL, - ret = fz_new_pixmap_with_bbox_and_data(ctx, cs, rect, samples), - fz_colorspace *cs, const fz_irect *rect, unsigned char *samples) + ret = fz_new_pixmap_with_bbox_and_data(ctx, cs, rect, seps, alpha, samples), + fz_colorspace *cs, const fz_irect *rect, fz_separations *seps, int alpha, unsigned char *samples) MUPDF_WRAP(mupdf_load_links, fz_link*, NULL, ret = fz_load_links(ctx, page), fz_page *page) MUPDF_WRAP(mupdf_pdf_create_annot, pdf_annot*, NULL, - ret = pdf_create_annot(ctx, doc, page, type), - pdf_document *doc, pdf_page *page, fz_annot_type type) -MUPDF_WRAP(mupdf_pdf_set_markup_annot_quadpoints, void*, NULL, - { pdf_set_markup_annot_quadpoints(ctx, doc, annot, qp, n); ret = (void*) -1; }, - pdf_document *doc, pdf_annot *annot, fz_point *qp, int n) + ret = pdf_create_annot(ctx, page, type), + pdf_page *page, fz_annot_type type) +MUPDF_WRAP(mupdf_pdf_set_annot_quad_points, void*, NULL, + { pdf_set_annot_quad_points(ctx, annot, n, v); ret = (void*) -1; }, + pdf_annot *annot, int n, const float *v) +MUPDF_WRAP(mupdf_pdf_set_text_annot_position, void*, NULL, + { pdf_set_text_annot_position(ctx, annot, pt); ret = (void*) -1; }, + pdf_annot *annot, fz_point pt) MUPDF_WRAP(mupdf_pdf_set_markup_appearance, void*, NULL, { pdf_set_markup_appearance(ctx, doc, annot, color, alpha, line_thickness, line_height); ret = (void*) -1; }, pdf_document *doc, pdf_annot *annot, float color[3], float alpha, float line_thickness, float line_height) -MUPDF_WRAP(mupdf_new_pixmap_from_image, fz_pixmap*, NULL, - ret = fz_new_pixmap_from_image(ctx, image, w, h), - fz_image *image, int w, int h) -MUPDF_WRAP(mupdf_new_image_from_data, fz_image*, NULL, - ret = fz_new_image_from_data(ctx, data, len), - unsigned char *data, int len) +MUPDF_WRAP(mupdf_get_pixmap_from_image, fz_pixmap*, NULL, + ret = fz_get_pixmap_from_image(ctx, image, subarea, trans, w, h), + fz_image *image, const fz_irect *subarea, fz_matrix *trans, int *w, int *h) +MUPDF_WRAP(mupdf_save_pixmap_as_png, void*, NULL, + { fz_save_pixmap_as_png(ctx, pixmap, filename); ret = (void*) -1; }, + fz_pixmap *pixmap, const char *filename) +MUPDF_WRAP(mupdf_new_image_from_buffer, fz_image*, NULL, + ret = fz_new_image_from_buffer(ctx, buffer), + fz_buffer *buffer) +MUPDF_WRAP(mupdf_new_buffer_from_shared_data, fz_buffer*, NULL, + ret = fz_new_buffer_from_shared_data(ctx, data, size), + const unsigned char *data, size_t size) +MUPDF_WRAP(mupdf_drop_buffer, void*, NULL, + { fz_drop_buffer(ctx, buf); ret = (void*) -1; }, + fz_buffer *buf)