lorid

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

commit d14cc816b394eaed6be63bcf1f0a24cc5b93c232
parent 533f89e679394a8d5287ce043ff74c9cfe0cfec7
Author: nibo <nibo@relim.de>
Date:   Fri,  2 Aug 2024 17:00:51 +0200

Render annotations when line item has a href

Diffstat:
Mout_pdf.c | 86++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 81 insertions(+), 5 deletions(-)

diff --git a/out_pdf.c b/out_pdf.c @@ -426,7 +426,7 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, struct TextLineItem *item, red = item->style->foreground_color->red / 255.0; green = item->style->foreground_color->green / 255.0; blue = item->style->foreground_color->blue / 255.0; - // printf("foreground_color: %s\n", the_rgb_color(style->foreground_color)); + // printf("foreground_color: %s\n", the_rgb_color(item->style->foreground_color)); if (!pdfioContentSetFillColorRGB(stream, red, green, blue)) { fprintf(stderr, "pdfioContentSetFillColorRGB failed.\n"); return false; @@ -806,7 +806,71 @@ static void text_free(struct Text **text) free(text); } -bool out_pdf_set_title(pdfio_file_t *pdf, struct ChoSong **songs) +static pdfio_dict_t *annot_create(pdfio_file_t *pdf, const char *uri, pdfio_rect_t *rect) +{ + pdfio_dict_t *annot = pdfioDictCreate(pdf); + if (!pdfioDictSetName(annot, "Subtype", "Link")) { + fprintf(stderr, "pdfioDictSetName failed.\n"); + return NULL; + } + if (!pdfioDictSetRect(annot, "Rect", rect)) { + fprintf(stderr, "pdfioDictSetRect failed.\n"); + return NULL; + } + pdfio_dict_t *action = pdfioDictCreate(pdf); + if (!pdfioDictSetName(action, "S", "URI")) { + fprintf(stderr, "pdfioDictSetName failed.\n"); + return NULL; + } + if (!pdfioDictSetString(action, "URI", uri)) { + fprintf(stderr, "pdfioDictSetString failed.\n"); + return NULL; + } + if (!pdfioDictSetDict(annot, "A", action)) { + fprintf(stderr, "pdfioDictSetDict failed.\n"); + return NULL; + } + return annot; +} + +static bool annots_create(pdfio_file_t *pdf, pdfio_array_t *annots, struct Text **text) +{ + struct TextLineItem *item; + pdfio_dict_t *annot; + pdfio_rect_t rect; + double y = MEDIABOX_HEIGHT - 25.0; + double width; + int t, tl, tli; + for (t = 0; text[t]; t++) { + for (tl = 0; text[t]->lines[tl]; tl++) { + if (text[t]->lines[tl]->items) { + for (tli = 0; text[t]->lines[tl]->items[tli]; tli++) { + item = text[t]->lines[tl]->items[tli]; + if (item->style->href) { + width = text_width(item); + rect.x1 = item->x; + rect.x2 = item->x + width; + rect.y1 = y - 2.0; + rect.y2 = y + item->style->font->size * 0.8; + annot = annot_create(pdf, item->style->href, &rect); + if (!annot) { + fprintf(stderr, "annot_create failed.\n"); + return false; + } + if (!pdfioArrayAppendDict(annots, annot)) { + fprintf(stderr, "pdfioArrayAppendDict failed.\n"); + return false; + } + } + } + } + y -= text[t]->lines[tl]->height; + } + } + return true; +} + +static bool out_pdf_set_title(pdfio_file_t *pdf, struct ChoSong **songs) { // Set pdf title only if single song exist if (songs[0] && !songs[1]) { @@ -881,19 +945,31 @@ bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, st fprintf(stderr, "text_create failed.\n"); return false; } + pdfio_array_t *annots = pdfioArrayCreate(pdf); + if (!annots_create(pdf, annots, text)) { + fprintf(stderr, "annotations_create failed.\n"); + return false; + } + printf("annots size: %ld\n", pdfioArrayGetSize(annots)); + if (pdfioArrayGetSize(annots) > 0) { + if (!pdfioDictSetArray(page1_dict, "Annots", annots)) { + fprintf(stderr, "pdfioDictSetArray failed.\n"); + return false; + } + } pdfio_array_t *color_array = pdfioArrayCreateColorFromStandard(pdf, 3, PDFIO_CS_ADOBE); if (!pdfioPageDictAddColorSpace(page1_dict, "rgbcolorspace", color_array)) { fprintf(stderr, "pdfioPageDictAddColorSpace failed.\n"); - return 1; + return false; } pdfio_stream_t *page1_stream = pdfioFileCreatePage(pdf, page1_dict); if (!pdfioContentSetFillColorSpace(page1_stream, "rgbcolorspace")) { fprintf(stderr, "pdfioContentSetFillColorSpace failed.\n"); - return 1; + return false; } if (!pdfioContentSetStrokeColorSpace(page1_stream, "rgbcolorspace")) { fprintf(stderr, "pdfioContentSetStrokeColorSpace failed.\n"); - return 1; + return false; } double y = MEDIABOX_HEIGHT - 25.0; int t, tl, tli;