lorid

convert chordpro to pdf
git clone git://git.relim.de/lorid.git
Log | Files | Refs | README | LICENSE

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:
Mout_pdf.c | 154+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mout_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);