commit e8c7549835417ffaa6d2288580e9a1747a8c8829
parent 1e75427cf32e69e0878e7f9dc5c01c68f46d7c1c
Author: nibo <nibo@relim.de>
Date: Wed, 15 Jan 2025 12:12:06 +0100
Wrap line if needed in pdf_texts_add_text()
Also put duplicate code in functions:
pdf_page_close_then_add, pdf_context_init
Diffstat:
| M | out_pdf.c | | | 154 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
| M | out_pdf.h | | | 1 | + |
2 files changed, 92 insertions(+), 63 deletions(-)
diff --git a/out_pdf.c b/out_pdf.c
@@ -648,7 +648,6 @@ pdf_text_show(pdfio_stream_t *stream, struct PDFText *text)
{
double red, green, blue;
bool unicode;
- // TODO: Store 'unicode' in PDFText too
if (!pdf_font_set(stream, text->style->font)) {
LOG_DEBUG("pdf_font_set failed.");
return false;
@@ -1172,6 +1171,24 @@ pdf_page_free(struct PDFPage *page)
free(page);
}
+static void
+pdf_context_init(struct PDFContext *ctx)
+{
+ ctx->content = NULL;
+ ctx->x = MARGIN_HORIZONTAL;
+ ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ ctx->text = 0;
+ ctx->image = 0;
+ ctx->diagram = 0;
+ ctx->page = 0;
+ ctx->toc_entry = 0;
+ ctx->spaces = NULL;
+ ctx->biggest_font_size = 0.0;
+ ctx->consumed_lyrics = 0;
+ ctx->prev_added_space = 0.0;
+ ctx->margin_bottom = MARGIN_BOTTOM;
+}
+
static struct PDFContent *
pdf_content_new(void)
{
@@ -1436,7 +1453,6 @@ text_above_update_positions(struct ChoLineItemAbove **aboves, size_t consumed_ly
}
}
-// TODO: This function doesn't create a new page if needed
static bool
pdf_texts_add_lyrics(
struct ChoLineItem *item,
@@ -1444,6 +1460,7 @@ pdf_texts_add_lyrics(
int i
)
{
+ printf("pdf_texts_add_lyrics '%s'\n", item->u.text->text);
struct PDFText ***texts;
struct SpaceNeeded **sp;
double width;
@@ -1552,7 +1569,33 @@ calc_x(double width, enum Alignment align)
return MARGIN_HORIZONTAL;
}
-// TODO: This function doesn't create a new page if needed
+static void
+pdf_page_close_then_add(struct PDFContext *ctx)
+{
+ ctx->content->pages[ctx->page]->texts = erealloc(
+ ctx->content->pages[ctx->page]->texts,
+ (ctx->text+1) * sizeof(struct PDFText *)
+ );
+ ctx->content->pages[ctx->page]->texts[ctx->text] = NULL;
+ ctx->content->pages[ctx->page]->images = erealloc(
+ ctx->content->pages[ctx->page]->images,
+ (ctx->image+1) * sizeof(struct PDFImage *)
+ );
+ ctx->content->pages[ctx->page]->images[ctx->image] = NULL;
+ ctx->content->pages[ctx->page]->diagrams = erealloc(
+ ctx->content->pages[ctx->page]->diagrams,
+ (ctx->diagram+1) * sizeof(struct ChordDiagram *)
+ );
+ ctx->content->pages[ctx->page]->diagrams[ctx->diagram] = NULL;
+ ctx->text = 0;
+ ctx->image = 0;
+ ctx->diagram = 0;
+ ctx->page++;
+ ctx->content->pages = erealloc(ctx->content->pages, (ctx->page+1) * sizeof(struct PDFPage *));
+ ctx->content->pages[ctx->page] = pdf_page_new();
+ ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+}
+
static bool
pdf_texts_add_text(
struct PDFContext *ctx,
@@ -1575,6 +1618,10 @@ pdf_texts_add_text(
if (width > LINE_WIDTH) {
char *t = (char *)&str;
while (width > LINE_WIDTH) {
+ if (ctx->y < ctx->margin_bottom) {
+ pdf_page_close_then_add(ctx);
+ texts = &ctx->content->pages[ctx->page]->texts;
+ }
index = text_find_fitting(t, style, 0.0, LINE_WIDTH);
if (index == EMPTY_INT) {
LOG_DEBUG("text_find_fitting failed.");
@@ -1631,6 +1678,10 @@ pdf_texts_add_text(
ctx->text++;
ctx->y -= 8.0 + style->font->size;
} else {
+ if (ctx->y < ctx->margin_bottom) {
+ pdf_page_close_then_add(ctx);
+ texts = &ctx->content->pages[ctx->page]->texts;
+ }
ctx->x = calc_x(width, align);
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
(*texts)[ctx->text] = pdf_text_new();
@@ -1722,18 +1773,13 @@ pdf_texts_add_toc_entry(
LOG_DEBUG("text_width failed.");
return false;
}
- if (width+MARGIN_HORIZONTAL > max_title_width) {
+ width += MARGIN_HORIZONTAL;
+ if (width > max_title_width) {
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();
+ pdf_page_close_then_add(ctx);
texts = &ctx->content->pages[ctx->page]->texts;
}
index = text_find_fitting(t, style, MARGIN_HORIZONTAL, max_title_width);
@@ -1748,7 +1794,6 @@ pdf_texts_add_toc_entry(
(*texts)[ctx->text]->style = cho_style_copy(style);
(*texts)[ctx->text]->x = MARGIN_HORIZONTAL;
(*texts)[ctx->text]->y = ctx->y;
- ctx->text++;
ctx->y -= 8.0 + style->font->size;
line_count++;
t += index + 1;
@@ -1758,15 +1803,11 @@ pdf_texts_add_toc_entry(
return false;
}
(*texts)[ctx->text]->width = width;
+ ctx->text++;
+ width += MARGIN_HORIZONTAL;
}
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();
+ pdf_page_close_then_add(ctx);
texts = &ctx->content->pages[ctx->page]->texts;
}
*texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
@@ -1816,6 +1857,11 @@ pdf_texts_add_toc_entry(
(*texts)[ctx->text]->style = cho_style_copy(style);
(*texts)[ctx->text]->x = MARGIN_HORIZONTAL;
(*texts)[ctx->text]->y = ctx->y;
+ width = text_width(entry->title, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
(*texts)[ctx->text]->width = width;
ctx->text++;
sprintf((char *)&page_no, "%d", entry->page_index+1);
@@ -1856,10 +1902,8 @@ pdf_toc_create(
struct PDFText ***texts;
struct ChoStyle *toc_style;
struct TocEntry **toc;
- ctx.text = 0;
- ctx.page = 0;
- ctx.x = MARGIN_HORIZONTAL;
- ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
+
+ pdf_context_init(&ctx);
ctx.content = pdf_content_new();
ctx.content->pages = emalloc(sizeof(struct PDFPage *));
ctx.content->pages[ctx.page] = pdf_page_new();
@@ -1923,20 +1967,12 @@ pdf_content_create(
struct PDFImage ***imgs;
struct PDFContext ctx;
struct ChordDiagram ***diagrams, **dgrams, **dgrams_begin;
- double width, height, margin_bottom;
+ double width, height;
+
+ pdf_context_init(&ctx);
if (config->output->diagram->show) {
- margin_bottom = 150.0;
- } else {
- margin_bottom = MARGIN_BOTTOM;
- }
- ctx.x = MARGIN_HORIZONTAL;
- ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
- ctx.text = 0;
- ctx.image = 0;
- ctx.diagram = 0;
- ctx.page = 0;
- ctx.toc_entry = 0;
- ctx.spaces = NULL;
+ ctx.margin_bottom = 150.0;
+ }
ctx.content = pdf_content_new();
ctx.content->pages = emalloc(sizeof(struct PDFPage *));
ctx.content->pages[ctx.page] = pdf_page_new();
@@ -1986,6 +2022,9 @@ pdf_content_create(
LOG_DEBUG("pdf_texts_add_text failed.");
return false;
}
+ texts = &ctx.content->pages[ctx.page]->texts;
+ imgs = &ctx.content->pages[ctx.page]->images;
+ diagrams = &ctx.content->pages[ctx.page]->diagrams;
}
}
for (m = songs[s]->metadata; *m; m++) {
@@ -2001,6 +2040,9 @@ pdf_content_create(
LOG_DEBUG("pdf_texts_add_text failed.");
return false;
}
+ texts = &ctx.content->pages[ctx.page]->texts;
+ imgs = &ctx.content->pages[ctx.page]->images;
+ diagrams = &ctx.content->pages[ctx.page]->diagrams;
}
}
ctx.y -= 30.0;
@@ -2010,6 +2052,9 @@ pdf_content_create(
LOG_DEBUG("pdf_texts_add_text failed.");
return false;
}
+ texts = &ctx.content->pages[ctx.page]->texts;
+ imgs = &ctx.content->pages[ctx.page]->images;
+ diagrams = &ctx.content->pages[ctx.page]->diagrams;
}
for (li = (*se)->lines; *li; li++) {
int item_index;
@@ -2105,7 +2150,7 @@ pdf_content_create(
ctx.y -= height;
}
}
- if (ctx.y < margin_bottom) {
+ if (ctx.y < ctx.margin_bottom) {
struct PDFText **tmp = NULL;
int tm = 0;
ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
@@ -2120,18 +2165,7 @@ pdf_content_create(
*texts = erealloc(*texts, (--ctx.text) * sizeof(struct PDFText *));
}
}
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = NULL;
- *imgs = erealloc(*imgs, (ctx.image+1) * sizeof(struct PDFImage *));
- (*imgs)[ctx.image] = NULL;
- *diagrams = erealloc(*diagrams, (ctx.diagram+1) * sizeof(struct ChordDiagram *));
- (*diagrams)[ctx.diagram] = NULL;
- ctx.text = 0;
- ctx.image = 0;
- ctx.diagram = 0;
- ctx.page++;
- ctx.content->pages = erealloc(ctx.content->pages, (ctx.page+1) * sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = pdf_page_new();
+ pdf_page_close_then_add(&ctx);
texts = &ctx.content->pages[ctx.page]->texts;
imgs = &ctx.content->pages[ctx.page]->images;
diagrams = &ctx.content->pages[ctx.page]->diagrams;
@@ -2162,6 +2196,9 @@ pdf_content_create(
LOG_DEBUG("pdf_texts_add_lyrics failed.");
return false;
}
+ texts = &ctx.content->pages[ctx.page]->texts;
+ imgs = &ctx.content->pages[ctx.page]->images;
+ diagrams = &ctx.content->pages[ctx.page]->diagrams;
} else {
*imgs = erealloc(*imgs, (ctx.image+1) * sizeof(struct PDFImage *));
(*imgs)[ctx.image] = pdf_image_new();
@@ -2196,6 +2233,9 @@ pdf_content_create(
}
free((*left_items)->u.text->text);
(*left_items)->u.text->text = tmp;
+ texts = &ctx.content->pages[ctx.page]->texts;
+ imgs = &ctx.content->pages[ctx.page]->images;
+ diagrams = &ctx.content->pages[ctx.page]->diagrams;
}
} else
if (pos->line_item_index != -1 && pos->text_index == -1) {
@@ -2221,23 +2261,11 @@ pdf_content_create(
left_items++;
}
ctx.y -= 8.0 + ctx.biggest_font_size;
- if (ctx.y < margin_bottom) {
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = NULL;
- *imgs = erealloc(*imgs, (ctx.image+1) * sizeof(struct PDFImage *));
- (*imgs)[ctx.image] = NULL;
- *diagrams = erealloc(*diagrams, (ctx.diagram+1) * sizeof(struct ChordDiagram *));
- (*diagrams)[ctx.diagram] = NULL;
- ctx.text = 0;
- ctx.image = 0;
- ctx.diagram = 0;
- ctx.page++;
- ctx.content->pages = erealloc(ctx.content->pages, (ctx.page+1) * sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = pdf_page_new();
+ if (ctx.y < ctx.margin_bottom) {
+ pdf_page_close_then_add(&ctx);
texts = &ctx.content->pages[ctx.page]->texts;
imgs = &ctx.content->pages[ctx.page]->images;
diagrams = &ctx.content->pages[ctx.page]->diagrams;
- ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
}
spaces_free(ctx.spaces);
ctx.spaces = NULL;
diff --git a/out_pdf.h b/out_pdf.h
@@ -89,6 +89,7 @@ struct PDFContext {
double biggest_font_size;
size_t consumed_lyrics;
double prev_added_space;
+ double margin_bottom;
};
char *out_pdf_create(const char *cho_filename, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config);