Skip to content

Commit

Permalink
update mupdf
Browse files Browse the repository at this point in the history
  • Loading branch information
kjk committed Nov 17, 2023
1 parent 396903b commit 10b1cf4
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 45 deletions.
29 changes: 29 additions & 0 deletions mupdf/docs/src/mutool-object-pdf-document.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,35 @@ With :title:`MuPDF` it is also possible to create, edit and manipulate :title:`P
var lang = pdfDocument.getLanguage();
.. method:: rearrangePages(pages)

|mutool_tag|

Rearrange (re-order and/or delete) pages in the `PDFDocument`.

The pages in the document will be rearranged according to the input list.
Any pages not listed will be removed, and pages may be duplicated by
listing them multiple times.

The PDF objects describing removed pages will remain in the file and take
up space (and can be recovered by forensic tools) unless you save with the
`garbage` option.

N.B. the `PDFDocument` should not be used for anything except saving after rearranging the pages (FIXME).

:arg pages: An array of page numbers (0-based).

|example_tag|

.. code-block:: javascript
var document = new Document.openDocument("my_pdf.pdf");
pdfDocument.rearrangePages([3,2]);
pdfDocument.save("fewer_pages.pdf", "garbage");
.. method:: save(fileName, options)

|mutool_tag|
Expand Down
5 changes: 5 additions & 0 deletions mupdf/include/mupdf/pdf/clean.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,9 @@ typedef struct
*/
void pdf_clean_file(fz_context *ctx, char *infile, char *outfile, char *password, pdf_clean_options *opts, int retainlen, char *retainlist[]);

/*
Recreate page tree to include only the pages listed in the array, in the order listed.
*/
void pdf_rearrange_pages(fz_context *ctx, pdf_document *doc, int count, int *pages);

#endif
31 changes: 31 additions & 0 deletions mupdf/platform/java/jni/pdfdocument.c
Original file line number Diff line number Diff line change
Expand Up @@ -1775,3 +1775,34 @@ FUN(PDFDocument_appendExplicitDestToURI)(JNIEnv *env, jclass cls, jstring jurl,
fz_free(ctx, uri);
return juri;
}

JNIEXPORT void JNICALL
FUN(PDFDocument_rearrangePages)(JNIEnv *env, jobject self, jobject jpages)
{
fz_context *ctx = get_context(env);
pdf_document *pdf = from_PDFDocument(env, self);
jsize len = 0;
int *pages = NULL;

if (!ctx || !pdf) return;

len = (*env)->GetArrayLength(env, jpages);
fz_try(ctx)
pages = fz_malloc_array(ctx, len, int);
fz_catch(ctx)
jni_rethrow_void(env, ctx);

(*env)->GetIntArrayRegion(env, jpages, 0, len, pages);
if ((*env)->ExceptionCheck(env))
{
fz_free(ctx, pages);
return;
}

fz_try(ctx)
pdf_rearrange_pages(ctx, pdf, len, pages);
fz_always(ctx)
fz_free(ctx, pages);
fz_catch(ctx)
jni_rethrow_void(env, ctx);
}
8 changes: 8 additions & 0 deletions mupdf/platform/java/mupdf_native.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ public PDFObject addPage(Rect mediabox, int rotate, PDFObject resources, String
public native boolean canBeSavedIncrementally();
public native boolean isRedacted();

public native void rearrangePages(int[] pages);

public native void save(String filename, String options);

protected native void nativeSaveWithStream(SeekableInputOutputStream stream, String options);
Expand Down
4 changes: 4 additions & 0 deletions mupdf/source/fitz/xml.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

#include <gumbo.h>

#define FZ_XML_MAX_DEPTH 4096

/* #define FZ_XML_SEQ */

static const struct { const char *name; int c; } html_entities[] = {
Expand Down Expand Up @@ -496,6 +498,8 @@ static void xml_emit_open_tag(fz_context *ctx, struct parser *parser, const char

parser->head = head;
parser->depth++;
if (parser->depth >= FZ_XML_MAX_DEPTH)
fz_throw(ctx, FZ_ERROR_SYNTAX, "too deep xml element nesting");
}

static void xml_emit_att_name(fz_context *ctx, struct parser *parser, const char *a, const char *b)
Expand Down
61 changes: 57 additions & 4 deletions mupdf/source/html/html-layout.c
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,17 @@ static float largest_max_width(fz_context *ctx, fz_html_box *box)
return r_max;
}

static void squish_block(fz_context *ctx, fz_html_box *box)
{
fz_html_box *child;

box->s.layout.b = box->s.layout.y;
if (box->type == BOX_FLOW)
return;
for (child = box->down; child; child = child->next)
squish_block(ctx, child);
}

static void layout_table_row(fz_context *ctx, layout_data *ld, fz_html_box *row, int ncol, struct column_width *colw, float spacing)
{
fz_html_box *cell, *child;
Expand Down Expand Up @@ -1100,7 +1111,11 @@ static void layout_table(fz_context *ctx, layout_data *ld, fz_html_box *box, fz_
}

/* TODO: remove 'vertical' margin adjustments across automatic page breaks */
if (layout_block_page_break(ctx, ld, &top->s.layout.b, box->style->page_break_before))
if (restart && restart->start != NULL)
{
/* We're still skipping, don't check for pagebreak before! */
}
else if (layout_block_page_break(ctx, ld, &top->s.layout.b, box->style->page_break_before))
eop = 1;

/* Position table in box flow, and add margins and padding */
Expand Down Expand Up @@ -1226,19 +1241,23 @@ static void layout_table(fz_context *ctx, layout_data *ld, fz_html_box *box, fz_
row->s.layout.x = box->s.layout.x;
row->s.layout.w = box->s.layout.w;
row->s.layout.y = row->s.layout.b = box->s.layout.b;
row->s.layout.b = row->s.layout.y;

if (restart && restart->start != NULL)
{
if (restart->start == row)
restart->start = NULL;
else
{
squish_block(ctx, row);
continue; /* still skipping */
}
}

layout_table_row(ctx, ld, row, ncol, colw, spacing);

/* If the row doesn't fit on the current page, break here and put the row on the next page.
* Unless the row was at the very start of the page, in which case it'll overfloaw instead.
* Unless the row was at the very start of the page, in which case it'll overflow instead.
* FIXME: Don't overflow, draw twice with offset to break it abruptly at the page border!
*/
if (ld->page_h > 0)
Expand Down Expand Up @@ -1268,6 +1287,22 @@ static void layout_table(fz_context *ctx, layout_data *ld, fz_html_box *box, fz_
fz_free(ctx, colw);
fz_catch(ctx)
fz_rethrow(ctx);

if (restart && restart->start != NULL)
{
/* We're still skipping, don't check for pagebreak after! */
}
else if (layout_block_page_break(ctx, ld, &top->s.layout.b, box->style->page_break_after))
{
if (restart && restart->end == NULL)
{
if (restart->potential)
restart->end = restart->potential;
else
restart->end = box;
return;
}
}
}

/* === LAYOUT BLOCKS === */
Expand Down Expand Up @@ -1315,7 +1350,11 @@ static void layout_block(fz_context *ctx, layout_data *ld, fz_html_box *box, fz_
}

/* TODO: remove 'vertical' margin adjustments across automatic page breaks */
if (layout_block_page_break(ctx, ld, &top->s.layout.b, style->page_break_before))
if (restart && restart->start != NULL)
{
/* We're still skipping, don't check for pagebreak before! */
}
else if (layout_block_page_break(ctx, ld, &top->s.layout.b, style->page_break_before))
eop = 1;

/* Important to remember that box->{x,y,w,b} are the coordinates of the content. The
Expand Down Expand Up @@ -1416,7 +1455,21 @@ static void layout_block(fz_context *ctx, layout_data *ld, fz_html_box *box, fz_
box->s.layout.b += fz_from_css_number_scale(style->line_height, em);
}

(void) layout_block_page_break(ctx, ld, &box->s.layout.b, style->page_break_after);
if (restart && restart->start != NULL)
{
/* We're still skipping, don't check for pagebreak after! */
}
else if (layout_block_page_break(ctx, ld, &box->s.layout.b, style->page_break_after))
{
if (restart && restart->end == NULL)
{
if (restart->potential)
restart->end = restart->potential;
else
restart->end = box;
return;
}
}
}

/* === LAYOUT === */
Expand Down
Loading

0 comments on commit 10b1cf4

Please sign in to comment.