commit e98c90da1f85c8303a8ff1769558a5af1db72e43
parent 75cd6db74b20fedf630def9b014d46d45dc5dd5d
Author: nibo <nibo@relim.de>
Date: Fri, 3 Jan 2025 11:27:37 +0100
Improve page breaking in toc rendering
Diffstat:
2 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/out_pdf.c b/out_pdf.c
@@ -1491,7 +1491,6 @@ pdf_texts_add_text(
return true;
}
-// TODO: This function doesn't create a new page if needed
static int
pdf_toc_page_count(
struct TocEntry **entries,
@@ -1570,6 +1569,16 @@ pdf_texts_add_toc_entry(
char *t = (char *)&tmp;
line_count = 0;
while (width > max_title_width) {
+ if (ctx->y < MARGIN_BOTTOM) {
+ *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->text] = NULL;
+ ctx->text = 0;
+ ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ ctx->page++;
+ ctx->content->pages = erealloc(ctx->content->pages, (ctx->page+1) * sizeof(struct PDFPage *));
+ ctx->content->pages[ctx->page] = pdf_page_new();
+ texts = &ctx->content->pages[ctx->page]->texts;
+ }
index = text_find_fitting(t, style, MARGIN_HORIZONTAL, max_title_width);
if (index == EMPTY_INT) {
LOG_DEBUG("text_find_fitting failed.");
@@ -1592,6 +1601,16 @@ pdf_texts_add_toc_entry(
return false;
}
}
+ if (ctx->y < MARGIN_BOTTOM) {
+ *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->text] = NULL;
+ ctx->text = 0;
+ ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ ctx->page++;
+ ctx->content->pages = erealloc(ctx->content->pages, (ctx->page+1) * sizeof(struct PDFPage *));
+ ctx->content->pages[ctx->page] = pdf_page_new();
+ texts = &ctx->content->pages[ctx->page]->texts;
+ }
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
(*texts)[ctx->text] = pdf_text_new();
(*texts)[ctx->text]->text = strdup(t);
@@ -1601,6 +1620,10 @@ pdf_texts_add_toc_entry(
ctx->text++;
sprintf((char *)&page_no, "%d", entry->page_index+1);
width = text_width(page_no, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
page_no_x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL - width;
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
@@ -1617,6 +1640,16 @@ pdf_texts_add_toc_entry(
ctx->text++;
ctx->y -= 8.0 + style->font->size;
} else {
+ if (ctx->y < MARGIN_BOTTOM) {
+ *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->text] = NULL;
+ ctx->text = 0;
+ ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ ctx->page++;
+ ctx->content->pages = erealloc(ctx->content->pages, (ctx->page+1) * sizeof(struct PDFPage *));
+ ctx->content->pages[ctx->page] = pdf_page_new();
+ texts = &ctx->content->pages[ctx->page]->texts;
+ }
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
(*texts)[ctx->text] = pdf_text_new();
(*texts)[ctx->text]->text = strdup(entry->title);
@@ -1626,6 +1659,10 @@ pdf_texts_add_toc_entry(
ctx->text++;
sprintf((char *)&page_no, "%d", entry->page_index+1);
width = text_width(page_no, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
page_no_x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL - width;
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
@@ -1685,16 +1722,6 @@ pdf_toc_create(
LOG_DEBUG("pdf_texts_add_toc_entry failed.");
return false;
}
- if (ctx.y < MARGIN_BOTTOM) {
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = NULL;
- ctx.text = 0;
- ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
- ctx.page++;
- ctx.content->pages = erealloc(ctx.content->pages, (ctx.page+1) * sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = pdf_page_new();
- texts = &ctx.content->pages[ctx.page]->texts;
- }
// TODO: create (multi)line with title, dots and the page number
/* space_for_dots = LINE_WIDTH;
space_for_dots -= width;
@@ -1708,6 +1735,7 @@ pdf_toc_create(
return false;
} */
}
+ texts = &ctx.content->pages[ctx.page]->texts;
*texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
(*texts)[ctx.text] = NULL;
ctx.page++;
diff --git a/out_pdf.h b/out_pdf.h
@@ -3,8 +3,8 @@
#define MEDIABOX_HEIGHT 841.995
#define MEDIABOX_WIDTH 595.35
-#define MARGIN_TOP 40.0
-#define MARGIN_BOTTOM 40.0
+#define MARGIN_TOP 50.0
+#define MARGIN_BOTTOM 50.0
// #define MARGIN_BOTTOM 180.0
#define MARGIN_HORIZONTAL 80.0
#define LINE_WIDTH MEDIABOX_WIDTH - MARGIN_HORIZONTAL * 2