commit 788651768a878f9ecf4c3168e4b3790d74cb3c63
parent 4c0fb05f7b569b0dbbfe31a6fb2553c39e76b888
Author: nibo <nibo@relim.de>
Date: Wed, 26 Mar 2025 18:13:32 +0100
Remove global vars by creating a pdf context
The goal here is to be able to generate a pdf
files concurrently from multiple threads. When
using global variables the threads overwrite
each others values but with a context variable
that holds the state this shouldn't happen.
Diffstat:
6 files changed, 718 insertions(+), 675 deletions(-)
diff --git a/src/chord_diagram.c b/src/chord_diagram.c
@@ -413,6 +413,7 @@ finger_to_char(int8_t finger)
static bool
string_diagram_draw(
+ struct PDFContext *ctx,
pdfio_stream_t *stream,
struct StringDiagram *diagram,
double x,
@@ -506,7 +507,7 @@ string_diagram_draw(
}
pdfio_obj_t *font_obj;
double name_width, centered_x;
- font_obj = out_pdf_fnt_obj_get_by_name("chord-diagram-regular-font");
+ font_obj = out_pdf_fnt_obj_get_by_name(ctx, "chord-diagram-regular-font");
if (!font_obj) {
LOG_DEBUG("out_pdf_fnt_obj_get_by_name failed.");
return false;
@@ -808,6 +809,7 @@ chord_diagrams_create(
bool
chord_diagram_draw(
+ struct PDFContext *ctx,
pdfio_stream_t *stream,
struct ChordDiagram *diagram,
double x,
@@ -817,7 +819,7 @@ chord_diagram_draw(
{
switch (diagram->type) {
case CDC_STRING:
- if (!string_diagram_draw(stream, diagram->u.sd, x, y, width)) {
+ if (!string_diagram_draw(ctx, stream, diagram->u.sd, x, y, width)) {
LOG_DEBUG("draw_string_chord_diagram failed.");
return false;
}
diff --git a/src/chord_diagram.h b/src/chord_diagram.h
@@ -14,7 +14,7 @@ enum Direction {
void chord_diagram_set_base_font(bool is_base_font);
struct ChordDiagram *chord_diagram_new();
void chord_diagram_free(struct ChordDiagram *d);
-bool chord_diagram_draw(pdfio_stream_t *stream, struct ChordDiagram *diagram, double x, double y, double width);
+bool chord_diagram_draw(struct PDFContext *ctx, pdfio_stream_t *stream, struct ChordDiagram *diagram, double x, double y, double width);
enum ChordDiagramContent chord_diagram_duplicate(struct ChordDiagram *diagram, struct ChordDiagram **custom_diagrams, int custom_diagrams_len, const char *name, const char *chord_to_copy, enum Instrument instrument);
struct ChordMap *chord_map_new(void);
diff --git a/src/chordpro.c b/src/chordpro.c
@@ -185,6 +185,7 @@ static const char *directive_type_enums[] = {
};
static const char *section_type_enums[] = {
+ "ST_UNINITIALIZED",
"ST_NEWSONG",
"ST_CHORUS",
"ST_VERSE",
@@ -4098,14 +4099,7 @@ static struct ChoDirective *
cho_directive_new(struct ChoContext *ctx)
{
struct ChoDirective *directive = emalloc(sizeof(struct ChoDirective));
- /*directive->dtype = -1;*/
- /*directive->stype = -1;*/
- /*directive->position = -1;*/
- /*directive->sprop = -1;*/
- /*directive->ttype = -1;*/
- /*directive->btype = -1;*/
- /*directive->meta = -1;*/
- /*directive->ctype = -1;*/
+ directive->stype = ST_UNINITIALIZED;
directive->style = cho_style_new_default(ctx);
return directive;
}
diff --git a/src/core.h b/src/core.h
@@ -72,6 +72,7 @@ enum ChordQualifier {
};
enum SectionType {
+ ST_UNINITIALIZED,
ST_NEWSONG,
ST_CHORUS,
ST_VERSE,
diff --git a/src/out_pdf.c b/src/out_pdf.c
@@ -8,21 +8,12 @@
#include <fontconfig/fontconfig.h>
#include <grapheme.h>
#include <math.h>
-#include <linux/limits.h>
#include "core.h"
#include "out_pdf.h"
#include "chordpro.h"
#include "config.h"
#include "chord_diagram.h"
-static struct Obj **g_fonts = NULL;
-static char g_cho_dirpath[PATH_MAX];
-static char g_current_font_name[200];
-static double g_current_font_size;
-static int g_current_page_index;
-static pdfio_file_t *g_pdf_file = NULL;
-static struct Config *g_config = NULL;
-
static struct Obj *
obj_new(void)
{
@@ -84,12 +75,12 @@ objs_add_obj(struct Obj ***array, struct Obj *obj)
}
pdfio_obj_t *
-out_pdf_fnt_obj_get_by_name(const char *name)
+out_pdf_fnt_obj_get_by_name(struct PDFContext *ctx, const char *name)
{
int i;
- for (i = 0; g_fonts[i]; i++) {
- if (!strcmp(g_fonts[i]->name, name)) {
- return g_fonts[i]->value;
+ for (i = 0; ctx->fonts[i]; i++) {
+ if (!strcmp(ctx->fonts[i]->name, name)) {
+ return ctx->fonts[i]->value;
}
}
printf("name '%s'\n", name);
@@ -325,7 +316,7 @@ fontpath_find(struct Font *font, enum FontType font_type)
}
static bool
-pdf_load_chord_diagram_fonts(void)
+pdf_load_chord_diagram_fonts(struct PDFContext *ctx)
{
struct Obj *fnt;
char *fontpath;
@@ -339,7 +330,7 @@ pdf_load_chord_diagram_fonts(void)
fnt = obj_new();
fnt->name = strdup("chord-diagram-regular-font");
if ((font_name = is_base_font(&font))) {
- fnt->value = pdfioFileCreateFontObjFromBase(g_pdf_file, font_name);
+ fnt->value = pdfioFileCreateFontObjFromBase(ctx->pdf_file, font_name);
chord_diagram_set_base_font(true);
} else {
fontpath = fontpath_find(&font, FT_TTF);
@@ -350,14 +341,14 @@ pdf_load_chord_diagram_fonts(void)
return false;
}
}
- fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, fontpath, true);
+ fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
free(fontpath);
}
- objs_add_obj(&g_fonts, fnt);
+ objs_add_obj(&ctx->fonts, fnt);
fnt = obj_new();
fnt->name = strdup("chord-diagram-symbols");
- fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, SYMBOLS_FILEPATH, true);
- objs_add_obj(&g_fonts, fnt);
+ fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, SYMBOLS_FILEPATH, true);
+ objs_add_obj(&ctx->fonts, fnt);
return true;
}
@@ -374,7 +365,7 @@ font_name_is_path(const char *name)
}
static bool
-pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
+pdf_load_fonts(struct PDFContext *ctx, struct Font **needed_fonts)
{
char *fontpath;
char **fontpaths = NULL;
@@ -389,7 +380,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
fnt->name = fnt_name_create(*f);
index = strs_get_index_if_in(fontpaths, fontpath);
if (index == -1) {
- fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, fontpath, true);
+ fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
if (!fnt->value) {
LOG_DEBUG("pdfioFileCreateFontObjFromFile failed.");
return false;
@@ -397,21 +388,21 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
strs_add(&fontpaths, fontpath);
util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", (*f)->name);
} else {
- fnt->value = g_fonts[index]->value;
+ fnt->value = ctx->fonts[index]->value;
}
free(fontpath);
// cho_font_print(*f);
- objs_add_obj(&g_fonts, fnt);
+ objs_add_obj(&ctx->fonts, fnt);
} else
if ((name = is_base_font(*f))) {
fnt = obj_new();
fnt->name = fnt_name_create(*f);
- fnt->value = pdfioFileCreateFontObjFromBase(g_pdf_file, name);
+ fnt->value = pdfioFileCreateFontObjFromBase(ctx->pdf_file, name);
if (!fnt->value) {
LOG_DEBUG("pdfioFileCreateFontObjFromBase failed.");
return false;
}
- objs_add_obj(&g_fonts, fnt);
+ objs_add_obj(&ctx->fonts, fnt);
} else {
fontpath = fontpath_find(*f, FT_TTF);
if (fontpath) {
@@ -419,7 +410,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
fnt->name = fnt_name_create(*f);
index = strs_get_index_if_in(fontpaths, fontpath);
if (index == -1) {
- fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, fontpath, true);
+ fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
if (!fnt->value) {
LOG_DEBUG("pdfioFileCreateFontObjFromFile failed.");
return false;
@@ -427,10 +418,10 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
strs_add(&fontpaths, fontpath);
util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath);
} else {
- fnt->value = g_fonts[index]->value;
+ fnt->value = ctx->fonts[index]->value;
}
// cho_font_print(*f);
- objs_add_obj(&g_fonts, fnt);
+ objs_add_obj(&ctx->fonts, fnt);
free(fontpath);
} else {
fontpath = fontpath_find(*f, FT_OTF);
@@ -439,7 +430,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
fnt->name = fnt_name_create(*f);
index = strs_get_index_if_in(fontpaths, fontpath);
if (index == -1) {
- fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, fontpath, true);
+ fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
if (!fnt->value) {
LOG_DEBUG("pdfioFileCreateFontObjFromFile failed.");
return false;
@@ -447,10 +438,10 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
strs_add(&fontpaths, fontpath);
util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath);
} else {
- fnt->value = g_fonts[index]->value;
+ fnt->value = ctx->fonts[index]->value;
}
// cho_font_print(*f);
- objs_add_obj(&g_fonts, fnt);
+ objs_add_obj(&ctx->fonts, fnt);
free(fontpath);
} else {
util_log(NULL, 0, LOG_ERR, "Didn't find font file for following font:");
@@ -460,8 +451,8 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
}
}
}
- if (config->output->diagram->show) {
- if (!pdf_load_chord_diagram_fonts()) {
+ if (ctx->config->output->diagram->show) {
+ if (!pdf_load_chord_diagram_fonts(ctx)) {
LOG_DEBUG("pdf_load_chord_diagram_fonts failed.");
return false;
}
@@ -471,7 +462,7 @@ pdf_load_fonts(struct Font **needed_fonts, struct Config *config)
}
static char *
-pdf_filename_generate_from_songs(struct ChoSong **songs)
+pdf_filename_generate_from_songs(struct PDFContext *ctx, struct ChoSong **songs)
{
char *filename;
char *normalized_title;
@@ -481,7 +472,7 @@ pdf_filename_generate_from_songs(struct ChoSong **songs)
if (len == 0)
return NULL;
if (len == 1) {
- if (!cho_metadata_value(songs[0]->metadata, "title", g_config->metadata_separator, &title, &unused)) {
+ if (!cho_metadata_value(songs[0]->metadata, "title", ctx->config->metadata_separator, &title, &unused)) {
LOG_DEBUG("cho_metadata_value failed.");
return NULL;
}
@@ -500,7 +491,12 @@ pdf_filename_generate_from_songs(struct ChoSong **songs)
}
static char *
-pdf_filepath_create(struct ChoSong **songs, const char *cho_filepath, const char *out)
+pdf_filepath_create(
+ struct PDFContext *ctx,
+ struct ChoSong **songs,
+ const char *cho_filepath,
+ const char *out
+)
{
char *pdf_filepath = NULL;
char *pdf_filename, *tmp;
@@ -509,7 +505,7 @@ pdf_filepath_create(struct ChoSong **songs, const char *cho_filepath, const char
pdf_filepath = file_extension_replace_or_add(cho_filepath, "pdf");
pdf_filename = filepath_basename(pdf_filepath);
} else {
- pdf_filename = pdf_filename_generate_from_songs(songs);
+ pdf_filename = pdf_filename_generate_from_songs(ctx, songs);
if (!pdf_filename) {
LOG_DEBUG("pdf_filename_generate_from_songs failed.");
return NULL;
@@ -561,14 +557,14 @@ pdf_filepath_create(struct ChoSong **songs, const char *cho_filepath, const char
}
static bool
-pdf_font_set(pdfio_stream_t *stream, struct Font *font)
+pdf_font_set(struct PDFContext *ctx, pdfio_stream_t *stream, struct Font *font)
{
static int page_index = 0;
char *name = fnt_name_create(font);
if (
- !strcmp(name, g_current_font_name) &&
- font->size == g_current_font_size &&
- g_current_page_index == page_index
+ !strcmp(name, ctx->current_font_name) &&
+ font->size == ctx->current_font_size &&
+ ctx->current_page_index == page_index
) {
free(name);
return true;
@@ -577,18 +573,18 @@ pdf_font_set(pdfio_stream_t *stream, struct Font *font)
LOG_DEBUG("pdfioContentSetTextFont failed.");
return false;
}
- strcpy(g_current_font_name, name);
- g_current_font_size = font->size;
- page_index = g_current_page_index;
+ strcpy(ctx->current_font_name, name);
+ ctx->current_font_size = font->size;
+ page_index = ctx->current_page_index;
free(name);
return true;
}
static double
-text_width(const char *text, struct ChoStyle *style)
+text_width(struct PDFContext *ctx, const char *text, struct ChoStyle *style)
{
char *name = fnt_name_create(style->font);
- pdfio_obj_t *font_obj = out_pdf_fnt_obj_get_by_name(name);
+ pdfio_obj_t *font_obj = out_pdf_fnt_obj_get_by_name(ctx, name);
if (!font_obj) {
LOG_DEBUG("out_pdf_fnt_obj_get_by_name failed.");
return -1.0;
@@ -598,20 +594,20 @@ text_width(const char *text, struct ChoStyle *style)
}
static double
-text_above_width(struct ChoLineItemAbove *above)
+text_above_width(struct PDFContext *ctx, struct ChoLineItemAbove *above)
{
double width;
if (above->is_chord) {
char *name;
name = cho_chord_name_generate(above->u.chord);
- width = text_width(name, above->u.chord->style);
+ width = text_width(ctx, name, above->u.chord->style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return ERROR;
}
free(name);
} else {
- width = text_width(above->u.annot->text, above->u.annot->style);
+ width = text_width(ctx, above->u.annot->text, above->u.annot->style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return ERROR;
@@ -634,6 +630,7 @@ find_whitespace(const char *str, size_t start)
static int
text_find_fitting(
+ struct PDFContext *ctx,
const char *str,
struct ChoStyle *style,
double x,
@@ -653,7 +650,7 @@ text_find_fitting(
return -1;
}
tmp[i] = 0;
- width = text_width((const char *)&tmp, style);
+ width = text_width(ctx, (const char *)&tmp, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return -1;
@@ -749,11 +746,11 @@ is_purest_white(struct RGBColor *color)
}
static bool
-pdf_text_show(pdfio_stream_t *stream, struct PDFText *text)
+pdf_text_show(struct PDFContext *ctx, pdfio_stream_t *stream, struct PDFText *text)
{
double red, green, blue;
bool unicode;
- if (!pdf_font_set(stream, text->style->font)) {
+ if (!pdf_font_set(ctx, stream, text->style->font)) {
LOG_DEBUG("pdf_font_set failed.");
return false;
}
@@ -814,7 +811,13 @@ pdf_text_show(pdfio_stream_t *stream, struct PDFText *text)
LOG_DEBUG("pdfioContentSetFillColorRGB failed.");
return false;
}
- if (!pdfioContentPathRect(stream, text->x - 2.0, text->y - 2.0, text->width + 4.0, text->style->font->size * 0.8 + 4.0)) {
+ if (!pdfioContentPathRect(
+ stream,
+ text->x - 2.0,
+ text->y - 2.0,
+ text->width + 4.0,
+ text->style->font->size * 0.8 + 4.0
+ )) {
LOG_DEBUG("pdfioContentPathRect failed.");
return false;
}
@@ -841,10 +844,10 @@ annot_page_link_add(
pdfio_array_t *destination;
rect.x1 = MARGIN_HORIZONTAL;
rect.x2 = MARGIN_HORIZONTAL + LINE_WIDTH;
- rect.y1 = ctx->y - 2.0;
- rect.y2 = ctx->y + (8.0 + font_size) * line_count - font_size * 0.8;
+ rect.y1 = ctx->t_ctx.y - 2.0;
+ rect.y2 = ctx->t_ctx.y + (8.0 + font_size) * line_count - font_size * 0.8;
page_index = entry->page_index + toc_page_count;
- annot = pdfioDictCreate(g_pdf_file);
+ annot = pdfioDictCreate(ctx->pdf_file);
if (!pdfioDictSetName(annot, "Subtype", "Link")) {
LOG_DEBUG("pdfioDictSetName failed.");
return false;
@@ -853,7 +856,7 @@ annot_page_link_add(
LOG_DEBUG("pdfioDictSetRect failed.");
return false;
}
- destination = pdfioArrayCreate(g_pdf_file);
+ destination = pdfioArrayCreate(ctx->pdf_file);
if (!pdfioArrayAppendNumber(destination, page_index)) {
LOG_DEBUG("pdfioArrayAppendNumber failed.");
return false;
@@ -872,7 +875,7 @@ annot_page_link_add(
LOG_DEBUG("pdfioDictSetArray failed.");
return false;
}
- if (!pdfioArrayAppendDict(ctx->content->pages[ctx->page]->annots, annot)) {
+ if (!pdfioArrayAppendDict(ctx->t_ctx.content->pages[ctx->t_ctx.page]->annots, annot)) {
LOG_DEBUG("pdfioArrayAppendDict failed.");
return false;
}
@@ -880,15 +883,20 @@ annot_page_link_add(
}
static bool
-annot_url_link_add(struct PDFContext *ctx, struct ChoStyle *style, double width)
+annot_url_link_add(
+ struct PDFContext *ctx,
+ struct PDFContentContext *c_ctx,
+ struct ChoStyle *style,
+ double width
+)
{
pdfio_rect_t rect;
pdfio_dict_t *annot, *action;
- rect.x1 = ctx->x;
- rect.x2 = ctx->x + width;
- rect.y1 = ctx->y - 2.0;
- rect.y2 = ctx->y + style->font->size * 0.8;
- annot = pdfioDictCreate(g_pdf_file);
+ rect.x1 = c_ctx->x;
+ rect.x2 = c_ctx->x + width;
+ rect.y1 = c_ctx->y - 2.0;
+ rect.y2 = c_ctx->y + style->font->size * 0.8;
+ annot = pdfioDictCreate(ctx->pdf_file);
if (!pdfioDictSetName(annot, "Subtype", "Link")) {
LOG_DEBUG("pdfioDictSetName failed.");
return false;
@@ -897,7 +905,7 @@ annot_url_link_add(struct PDFContext *ctx, struct ChoStyle *style, double width)
LOG_DEBUG("pdfioDictSetRect failed.");
return false;
}
- action = pdfioDictCreate(g_pdf_file);
+ action = pdfioDictCreate(ctx->pdf_file);
if (!pdfioDictSetName(action, "S", "URI")) {
LOG_DEBUG("pdfioDictSetName failed.");
return false;
@@ -910,7 +918,7 @@ annot_url_link_add(struct PDFContext *ctx, struct ChoStyle *style, double width)
LOG_DEBUG("pdfioDictSetDict failed.");
return false;
}
- if (!pdfioArrayAppendDict(ctx->content->pages[ctx->page]->annots, annot)) {
+ if (!pdfioArrayAppendDict(c_ctx->content->pages[c_ctx->page]->annots, annot)) {
LOG_DEBUG("pdfioArrayAppendDict failed.");
return false;
}
@@ -918,18 +926,18 @@ annot_url_link_add(struct PDFContext *ctx, struct ChoStyle *style, double width)
}
static bool
-pdf_set_title(pdfio_file_t *pdf, struct ChoSong **songs)
+pdf_set_title(struct PDFContext *ctx, struct ChoSong **songs)
{
// INFO: Set pdf title only if a single song exist
if (songs[0] && !songs[1]) {
char *title;
struct ChoStyle *unused;
- if (!cho_metadata_value(songs[0]->metadata, "title", g_config->metadata_separator, &title, &unused)) {
+ if (!cho_metadata_value(songs[0]->metadata, "title", ctx->config->metadata_separator, &title, &unused)) {
LOG_DEBUG("cho_metadata_value failed.");
return false;
}
if (title) {
- pdfioFileSetTitle(pdf, title);
+ pdfioFileSetTitle(ctx->pdf_file, title);
free(title);
return true;
}
@@ -940,17 +948,17 @@ pdf_set_title(pdfio_file_t *pdf, struct ChoSong **songs)
static pdfio_stream_t *
pdf_page_create(
- pdfio_file_t *pdf,
+ struct PDFContext *ctx,
struct PDFImage **imgs,
pdfio_array_t *annots
)
{
pdfio_dict_t *page_dict;
pdfio_stream_t *page_stream;
- pdfio_array_t *color_array = pdfioArrayCreateColorFromStandard(pdf, 3, PDFIO_CS_ADOBE);
+ pdfio_array_t *color_array = pdfioArrayCreateColorFromStandard(ctx->pdf_file, 3, PDFIO_CS_ADOBE);
struct Obj **f;
struct PDFImage **i;
- page_dict = pdfioDictCreate(pdf);
+ page_dict = pdfioDictCreate(ctx->pdf_file);
if (!pdfioPageDictAddColorSpace(page_dict, "rgbcolorspace", color_array)) {
LOG_DEBUG("pdfioPageDictAddColorSpace failed.");
return NULL;
@@ -967,13 +975,13 @@ pdf_page_create(
}
}
}
- for (f = g_fonts; *f; f++) {
+ for (f = ctx->fonts; *f; f++) {
if (!pdfioPageDictAddFont(page_dict, (*f)->name, (*f)->value)) {
LOG_DEBUG("pdfioPageDictAddFont failed.");
return NULL;
}
}
- page_stream = pdfioFileCreatePage(pdf, page_dict);
+ page_stream = pdfioFileCreatePage(ctx->pdf_file, page_dict);
if (!pdfioContentSetFillColorSpace(page_stream, "rgbcolorspace")) {
LOG_DEBUG("pdfioContentSetFillColorSpace failed.");
return NULL;
@@ -1026,7 +1034,7 @@ image_height(struct ChoImage *image, pdfio_obj_t *obj)
}
static char *
-image_name(struct ChoImage *image)
+image_name(struct PDFContext *ctx, struct ChoImage *image)
{
char tmp[PATH_MAX];
char *image_path;
@@ -1034,7 +1042,7 @@ image_name(struct ChoImage *image)
if (strchr(image->src, '/')) {
image_path = image->src;
} else {
- strcpy((char *)&tmp, g_cho_dirpath);
+ strcpy((char *)&tmp, ctx->cho_dirpath);
strcat((char *)&tmp, "/");
strcat((char *)&tmp, image->src);
image_path = (char *)&tmp;
@@ -1050,7 +1058,7 @@ image_name(struct ChoImage *image)
}
static bool
-pdf_load_images(struct Obj ***images, pdfio_file_t *file, struct ChoSong **songs)
+pdf_load_images(struct PDFContext *ctx, struct Obj ***images, struct ChoSong **songs)
{
struct ChoSong **s;
struct ChoSection **se;
@@ -1066,10 +1074,10 @@ pdf_load_images(struct Obj ***images, pdfio_file_t *file, struct ChoSong **songs
for (it = (*li)->items; *it; it++) {
if (!(*it)->is_text) {
memset(filepath, 0, PATH_MAX);
- strcpy((char *)&filepath, g_cho_dirpath);
+ strcpy((char *)&filepath, ctx->cho_dirpath);
strcat((char *)&filepath, "/");
strcat((char *)&filepath, (*it)->u.image->src);
- name = image_name((*it)->u.image);
+ name = image_name(ctx, (*it)->u.image);
if (!name) {
LOG_DEBUG("image_name failed.");
return false;
@@ -1083,7 +1091,7 @@ pdf_load_images(struct Obj ***images, pdfio_file_t *file, struct ChoSong **songs
} else {
image_filepath = (char *)&filepath;
}
- (*images)[i]->value = pdfioFileCreateImageObjFromFile(file, image_filepath, true);
+ (*images)[i]->value = pdfioFileCreateImageObjFromFile(ctx->pdf_file, image_filepath, true);
if (!(*images)[i]->value) {
LOG_DEBUG("pdfioFileCreateImageObjFromFile failed.");
return false;
@@ -1123,6 +1131,7 @@ pdf_get_chords(struct ChoSong *song, struct ChoChord ***chords)
static double
line_width_until_text_above(
+ struct PDFContext *ctx,
struct ChoLineItem **items,
struct ChoLineItemAbove *above,
struct Obj **img_objs,
@@ -1161,7 +1170,7 @@ line_width_until_text_above(
if (items[i]->is_text) {
text = items[i]->u.text;
name = fnt_name_create(text->style->font);
- font_obj = out_pdf_fnt_obj_get_by_name(name);
+ font_obj = out_pdf_fnt_obj_get_by_name(ctx, name);
if (!font_obj) {
LOG_DEBUG("out_pdf_fnt_obj_get_by_name failed.");
return ERROR;
@@ -1176,7 +1185,7 @@ line_width_until_text_above(
}
free(name);
} else {
- name = image_name(items[i]->u.image);
+ name = image_name(ctx, items[i]->u.image);
if (!name) {
LOG_DEBUG("image_name failed.");
return ERROR;
@@ -1247,13 +1256,13 @@ toc_entry_free(struct TocEntry *entry)
}
static struct PDFPage *
-pdf_page_new(void)
+pdf_page_new(struct PDFContext *ctx)
{
struct PDFPage *page = emalloc(sizeof(struct PDFPage));
page->texts = NULL;
page->images = NULL;
page->diagrams = NULL;
- page->annots = pdfioArrayCreate(g_pdf_file);
+ page->annots = pdfioArrayCreate(ctx->pdf_file);
return page;
}
@@ -1288,21 +1297,21 @@ pdf_page_free(struct PDFPage *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;
+pdf_content_context_init(struct PDFContentContext *c_ctx)
+{
+ c_ctx->content = NULL;
+ c_ctx->x = MARGIN_HORIZONTAL;
+ c_ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ c_ctx->text = 0;
+ c_ctx->image = 0;
+ c_ctx->diagram = 0;
+ c_ctx->page = 0;
+ c_ctx->toc_entry = 0;
+ c_ctx->spaces = NULL;
+ c_ctx->biggest_font_size = 0.0;
+ c_ctx->consumed_lyrics = 0;
+ c_ctx->prev_added_space = 0.0;
+ c_ctx->margin_bottom = MARGIN_BOTTOM;
}
static struct PDFContent *
@@ -1350,6 +1359,7 @@ spaces_free(struct SpaceNeeded **spaces)
static bool
calc_space_between_text_above(
+ struct PDFContext *ctx,
struct ChoLineItem **items,
struct ChoLineItemAbove **text_above,
struct Obj **img_objs,
@@ -1372,18 +1382,18 @@ calc_space_between_text_above(
double width_until_cur;
double width_until_prev;
double prev_width;
- width_until_cur = line_width_until_text_above(items, text_above[i], img_objs, NULL);
+ width_until_cur = line_width_until_text_above(ctx, items, text_above[i], img_objs, NULL);
if (width_until_cur == ERROR) {
LOG_DEBUG("line_width_until_text_above failed.");
return false;
}
i--;
- width_until_prev = line_width_until_text_above(items, text_above[i], img_objs, &space);
+ width_until_prev = line_width_until_text_above(ctx, items, text_above[i], img_objs, &space);
if (width_until_prev == ERROR) {
LOG_DEBUG("line_width_until_text_above failed.");
return false;
}
- prev_width = text_above_width(text_above[i]);
+ prev_width = text_above_width(ctx, text_above[i]);
if (prev_width == ERROR) {
LOG_DEBUG("text_above_width failed.");
return false;
@@ -1406,11 +1416,17 @@ calc_space_between_text_above(
}
static double
-item_width(struct ChoLineItem *item, int i, struct SpaceNeeded **spaces, struct Obj **img_objs)
+item_width(
+ struct PDFContext *ctx,
+ struct ChoLineItem *item,
+ int i,
+ struct SpaceNeeded **spaces,
+ struct Obj **img_objs
+)
{
double width;
if (item->is_text) {
- width = text_width(item->u.text->text, item->u.text->style);
+ width = text_width(ctx, item->u.text->text, item->u.text->style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return ERROR;
@@ -1426,7 +1442,7 @@ item_width(struct ChoLineItem *item, int i, struct SpaceNeeded **spaces, struct
} else {
char *name;
pdfio_obj_t *obj;
- name = image_name(item->u.image);
+ name = image_name(ctx, item->u.image);
if (!name) {
LOG_DEBUG("image_name failed.");
return ERROR;
@@ -1444,6 +1460,7 @@ item_width(struct ChoLineItem *item, int i, struct SpaceNeeded **spaces, struct
static struct CharPosition *
items_find_position_to_break_line(
+ struct PDFContext *ctx,
struct ChoLineItem **items,
struct SpaceNeeded **spaces,
struct Obj **img_objs
@@ -1457,7 +1474,7 @@ items_find_position_to_break_line(
struct ChoLineItem **it = items;
int i;
for (i = 0; it[i]; i++) {
- d = item_width(it[i], i, spaces, img_objs);
+ d = item_width(ctx, it[i], i, spaces, img_objs);
if (d == ERROR) {
LOG_DEBUG("item_width failed.");
return NULL;
@@ -1466,6 +1483,7 @@ items_find_position_to_break_line(
if (it[i]->is_text) {
pos->line_item_index = i;
pos->text_index = text_find_fitting(
+ ctx,
it[i]->u.text->text,
it[i]->u.text->style,
width,
@@ -1488,7 +1506,12 @@ items_find_position_to_break_line(
}
static double
-images_find_biggest_height(struct ChoLineItem **left_items, int line_item_index, struct Obj **img_objs)
+images_find_biggest_height(
+ struct PDFContext *ctx,
+ struct ChoLineItem **left_items,
+ int line_item_index,
+ struct Obj **img_objs
+)
{
struct ChoLineItem **it;
char *name;
@@ -1502,7 +1525,7 @@ images_find_biggest_height(struct ChoLineItem **left_items, int line_item_index,
}
for (it = left_items; *it && i <= end; it++, i++) {
if (!(*it)->is_text) {
- name = image_name((*it)->u.image);
+ name = image_name(ctx, (*it)->u.image);
if (!name) {
LOG_DEBUG("image_name failed.");
return ERROR;
@@ -1523,7 +1546,11 @@ images_find_biggest_height(struct ChoLineItem **left_items, int line_item_index,
}
static int
-text_above_find_index_to_break_line(struct ChoLineItem **items, struct ChoLineItemAbove **text_above, struct CharPosition *pos)
+text_above_find_index_to_break_line(
+ struct ChoLineItem **items,
+ struct ChoLineItemAbove **text_above,
+ struct CharPosition *pos
+)
{
int position = 0;
int i, k;
@@ -1569,112 +1596,6 @@ text_above_update_positions(struct ChoLineItemAbove **aboves, size_t consumed_ly
}
}
-static bool
-pdf_texts_add_lyrics(
- struct ChoLineItem *item,
- struct PDFContext *ctx,
- int i
-)
-{
- struct PDFText ***texts;
- struct SpaceNeeded **sp;
- double width;
- int t = 0;
- int c;
- texts = &ctx->content->pages[ctx->page]->texts;
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- if (!ctx->spaces) {
- (*texts)[ctx->text]->text = strdup(item->u.text->text);
- (*texts)[ctx->text]->style = cho_style_copy(item->u.text->style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- width = text_width(item->u.text->text, item->u.text->style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- (*texts)[ctx->text]->width = width;
- if (item->u.text->style->href) {
- if (!annot_url_link_add(ctx, item->u.text->style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->x += width;
- if ((*texts)[ctx->text]->style->font->size > ctx->biggest_font_size) {
- ctx->biggest_font_size = (*texts)[ctx->text]->style->font->size;
- }
- ctx->consumed_lyrics += strlen((*texts)[ctx->text]->text);
- ctx->text++;
- return true;
- }
- for (c = 0; item->u.text->text[c]; c++) {
- (*texts)[ctx->text]->text = erealloc((*texts)[ctx->text]->text, (t+1) * sizeof(char));
- (*texts)[ctx->text]->text[t] = item->u.text->text[c];
- t++;
- for (sp = ctx->spaces; *sp; sp++) {
- if ((*sp)->line_item_index == i && (*sp)->text_index == c) {
- size_t len = grapheme_next_character_break_utf8(&item->u.text->text[c], 10);
- size_t i;
- for (i = 0; i<len-1; i++, t++) {
- c++;
- (*texts)[ctx->text]->text = erealloc((*texts)[ctx->text]->text, (t+1) * sizeof(char));
- (*texts)[ctx->text]->text[t] = item->u.text->text[c];
- }
- (*texts)[ctx->text]->text = erealloc((*texts)[ctx->text]->text, (t+1) * sizeof(char));
- (*texts)[ctx->text]->text[t] = 0;
- (*texts)[ctx->text]->style = cho_style_copy(item->u.text->style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- width = text_width((*texts)[ctx->text]->text, item->u.text->style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- (*texts)[ctx->text]->width = width;
- if (item->u.text->style->href) {
- if (!annot_url_link_add(ctx, item->u.text->style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->x += width;
- ctx->x += (*sp)->amount;
- t = 0;
- ctx->consumed_lyrics += strlen((*texts)[ctx->text]->text);
- ctx->text++;
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- }
- }
- }
- (*texts)[ctx->text]->text = erealloc((*texts)[ctx->text]->text, (t+1) * sizeof(char));
- (*texts)[ctx->text]->text[t] = 0;
- (*texts)[ctx->text]->style = cho_style_copy(item->u.text->style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- width = text_width((*texts)[ctx->text]->text, item->u.text->style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- (*texts)[ctx->text]->width = width;
- if (item->u.text->style->href) {
- if (!annot_url_link_add(ctx, item->u.text->style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->x += width;
- if ((*texts)[ctx->text]->style->font->size > ctx->biggest_font_size) {
- ctx->biggest_font_size = (*texts)[ctx->text]->style->font->size;
- }
- ctx->consumed_lyrics += strlen((*texts)[ctx->text]->text);
- ctx->text++;
- return true;
-}
-
static double
calc_x(double width, enum Alignment align)
{
@@ -1795,7 +1716,11 @@ numeral_system_number_to_str(enum NumeralSystem system, int n)
}
static bool
-pdf_page_add_page_no(struct PDFContext *ctx, enum NumeralSystem numeral_system)
+pdf_page_add_page_no(
+ struct PDFContext *ctx,
+ struct PDFContentContext *c_ctx,
+ enum NumeralSystem numeral_system
+)
{
struct PDFText ***texts;
struct ChoStyle *style;
@@ -1804,25 +1729,25 @@ pdf_page_add_page_no(struct PDFContext *ctx, enum NumeralSystem numeral_system)
style = cho_style_new();
style->font->name = strdup(DEFAULT_FONT);
- texts = &ctx->content->pages[ctx->page]->texts;
- page_no = numeral_system_number_to_str(numeral_system, ctx->page+1);
+ texts = &c_ctx->content->pages[c_ctx->page]->texts;
+ page_no = numeral_system_number_to_str(numeral_system, c_ctx->page+1);
if (!page_no) {
LOG_DEBUG("numeral_system_number_to_str failed.");
return false;
}
- width = text_width(page_no, style);
+ width = text_width(ctx, page_no, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(page_no);
- (*texts)[ctx->text]->style = style;
- (*texts)[ctx->text]->x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width;
- (*texts)[ctx->text]->y = MARGIN_BOTTOM / 2;
- (*texts)[ctx->text]->width = width;
- switch (g_config->output->page_no->align) {
+ *texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[c_ctx->text] = pdf_text_new();
+ (*texts)[c_ctx->text]->text = strdup(page_no);
+ (*texts)[c_ctx->text]->style = style;
+ (*texts)[c_ctx->text]->x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width;
+ (*texts)[c_ctx->text]->y = MARGIN_BOTTOM / 2;
+ (*texts)[c_ctx->text]->width = width;
+ switch (ctx->config->output->page_no->align) {
case A_LEFT:
x = MARGIN_HORIZONTAL / 2;
break;
@@ -1833,41 +1758,45 @@ pdf_page_add_page_no(struct PDFContext *ctx, enum NumeralSystem numeral_system)
x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width;
break;
default:
- util_log(NULL, 0, LOG_ERR, "Invalid Alignment enum value '%d'.", g_config->output->page_no->align);
+ util_log(NULL, 0, LOG_ERR, "Invalid Alignment enum value '%d'.", ctx->config->output->page_no->align);
return false;
}
- (*texts)[ctx->text]->x = x;
- ctx->text++;
+ (*texts)[c_ctx->text]->x = x;
+ c_ctx->text++;
return true;
}
static bool
-pdf_page_close_then_add(struct PDFContext *ctx, enum NumeralSystem numeral_system)
+pdf_page_close_then_add(
+ struct PDFContext *ctx,
+ struct PDFContentContext *c_ctx,
+ enum NumeralSystem numeral_system
+)
{
- ctx->content->pages[ctx->page]->texts = erealloc(
- ctx->content->pages[ctx->page]->texts,
- (ctx->text+1) * sizeof(struct PDFText *)
+ c_ctx->content->pages[c_ctx->page]->texts = erealloc(
+ c_ctx->content->pages[c_ctx->page]->texts,
+ (c_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 *)
+ c_ctx->content->pages[c_ctx->page]->texts[c_ctx->text] = NULL;
+ c_ctx->content->pages[c_ctx->page]->images = erealloc(
+ c_ctx->content->pages[c_ctx->page]->images,
+ (c_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 *)
+ c_ctx->content->pages[c_ctx->page]->images[c_ctx->image] = NULL;
+ c_ctx->content->pages[c_ctx->page]->diagrams = erealloc(
+ c_ctx->content->pages[c_ctx->page]->diagrams,
+ (c_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;
- if (g_config->output->page_no->show) {
- if (!pdf_page_add_page_no(ctx, numeral_system)) {
+ c_ctx->content->pages[c_ctx->page]->diagrams[c_ctx->diagram] = NULL;
+ c_ctx->text = 0;
+ c_ctx->image = 0;
+ c_ctx->diagram = 0;
+ c_ctx->page++;
+ c_ctx->content->pages = erealloc(c_ctx->content->pages, (c_ctx->page+1) * sizeof(struct PDFPage *));
+ c_ctx->content->pages[c_ctx->page] = pdf_page_new(ctx);
+ c_ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ if (ctx->config->output->page_no->show) {
+ if (!pdf_page_add_page_no(ctx, c_ctx, numeral_system)) {
LOG_DEBUG("pdf_page_add_page_no failed.");
return false;
}
@@ -1875,121 +1804,9 @@ pdf_page_close_then_add(struct PDFContext *ctx, enum NumeralSystem numeral_syste
return true;
}
-static bool
-pdf_texts_add_text(
- struct PDFContext *ctx,
- const char *text,
- struct ChoStyle *style,
- enum Alignment align,
- enum NumeralSystem numeral_system
-)
-{
- struct PDFText ***texts;
- char str[strlen(text)+1];
- double width;
- int index;
- strcpy((char *)&str, text);
- texts = &ctx->content->pages[ctx->page]->texts;
- width = text_width(text, style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- if (width > LINE_WIDTH) {
- char *t = (char *)&str;
- while (width > LINE_WIDTH) {
- if (ctx->y < ctx->margin_bottom) {
- if (!pdf_page_close_then_add(ctx, numeral_system)) {
- LOG_DEBUG("pdf_page_close_then_add failed.");
- return false;
- }
- 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.");
- return false;
- }
- t[index] = 0;
- width = text_width(t, style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- ctx->x = calc_x(width, align);
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(t);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = width;
- if (style->href) {
- if (!annot_url_link_add(ctx, style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->text++;
- ctx->y -= 8.0 + style->font->size;
- t += index+1;
- width = text_width(t, style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- }
- width = text_width(t, style);
- if (width == ERROR) {
- LOG_DEBUG("text_width failed.");
- return false;
- }
- ctx->x = calc_x(width, align);
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(t);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = width;
- if (style->href) {
- if (!annot_url_link_add(ctx, style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->text++;
- ctx->y -= 8.0 + style->font->size;
- } else {
- if (ctx->y < ctx->margin_bottom) {
- if (!pdf_page_close_then_add(ctx, numeral_system)) {
- LOG_DEBUG("pdf_page_close_then_add failed.");
- return false;
- }
- 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();
- (*texts)[ctx->text]->text = strdup(text);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = ctx->x;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = width;
- if (style->href) {
- if (!annot_url_link_add(ctx, style, width)) {
- LOG_DEBUG("annot_url_link_add failed.");
- return false;
- }
- }
- ctx->text++;
- ctx->y -= 8.0 + style->font->size;
- }
- return true;
-}
-
static int
pdf_toc_page_count(
+ struct PDFContext *ctx,
struct TocEntry **entries,
struct ChoStyle *style,
double max_title_width
@@ -2007,7 +1824,7 @@ pdf_toc_page_count(
int index;
char tmp[strlen((*toc)->title)+1];
strcpy((char *)&tmp, (*toc)->title);
- width = text_width((*toc)->title, style);
+ width = text_width(ctx, (*toc)->title, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return -1;
@@ -2016,7 +1833,7 @@ pdf_toc_page_count(
if (width > max_title_width) {
char *t = (char *)&tmp;
while (width > max_title_width) {
- index = text_find_fitting(t, style, MARGIN_HORIZONTAL, max_title_width);
+ index = text_find_fitting(ctx, t, style, MARGIN_HORIZONTAL, max_title_width);
if (index == EMPTY_INT) {
LOG_DEBUG("text_find_fitting failed.");
return -1;
@@ -2024,7 +1841,7 @@ pdf_toc_page_count(
t[index] = 0;
y -= 8.0 + style->font->size;
t += index + 1;
- width = text_width(t, style);
+ width = text_width(ctx, t, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return -1;
@@ -2065,14 +1882,14 @@ pdf_texts_add_toc_entry(
)
{
struct PDFText ***texts;
- texts = &ctx->content->pages[ctx->page]->texts;
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
double width, page_no_x, end_of_title_x, width_between_title_and_page_no, available_dots_width;
double page_no_width, dots_width;
int index, line_count;
char tmp[strlen(entry->title)+1];
char page_no[11+1];
strcpy((char *)&tmp, entry->title);
- width = text_width(entry->title, style);
+ width = text_width(ctx, entry->title, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
@@ -2081,59 +1898,59 @@ pdf_texts_add_toc_entry(
char *t = (char *)&tmp;
line_count = 0;
while (width+MARGIN_HORIZONTAL > max_song_title_width) {
- if (ctx->y < MARGIN_BOTTOM) {
- if (!pdf_page_close_then_add(ctx, NUS_ROMAN)) {
+ if (ctx->t_ctx.y < MARGIN_BOTTOM) {
+ if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUS_ROMAN)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx->content->pages[ctx->page]->texts;
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
}
- index = text_find_fitting(t, style, MARGIN_HORIZONTAL, max_song_title_width);
+ index = text_find_fitting(ctx, t, style, MARGIN_HORIZONTAL, max_song_title_width);
if (index == EMPTY_INT) {
LOG_DEBUG("text_find_fitting failed.");
return false;
}
t[index] = 0;
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(t);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = MARGIN_HORIZONTAL;
- (*texts)[ctx->text]->y = ctx->y;
- ctx->y -= 8.0 + style->font->size;
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(t);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ ctx->t_ctx.y -= 8.0 + style->font->size;
line_count++;
- width = text_width(t, style);
+ width = text_width(ctx, t, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
- (*texts)[ctx->text]->width = width;
+ (*texts)[ctx->t_ctx.text]->width = width;
t += index + 1;
- width = text_width(t, style);
+ width = text_width(ctx, t, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
- ctx->text++;
+ ctx->t_ctx.text++;
}
- if (ctx->y < MARGIN_BOTTOM) {
- if (!pdf_page_close_then_add(ctx, NUS_ROMAN)) {
+ if (ctx->t_ctx.y < MARGIN_BOTTOM) {
+ if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUS_ROMAN)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx->content->pages[ctx->page]->texts;
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
}
end_of_title_x = width;
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(t);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = MARGIN_HORIZONTAL;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = width;
- ctx->text++;
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(t);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ (*texts)[ctx->t_ctx.text]->width = width;
+ ctx->t_ctx.text++;
sprintf((char *)&page_no, "%d", entry->page_index+1);
- width = text_width(page_no, style);
+ width = text_width(ctx, page_no, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
@@ -2148,52 +1965,52 @@ pdf_texts_add_toc_entry(
return false;
}
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(dots);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
- (*texts)[ctx->text]->y = ctx->y;
- ctx->text++;
-
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(page_no);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = page_no_x;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = width;
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(dots);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ ctx->t_ctx.text++;
+
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(page_no);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = page_no_x;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ (*texts)[ctx->t_ctx.text]->width = width;
line_count++;
if (!annot_page_link_add(ctx, entry, toc_page_count, line_count, style->font->size)) {
LOG_DEBUG("annot_page_link_add");
return false;
}
- ctx->text++;
- ctx->y -= 8.0 + style->font->size;
+ ctx->t_ctx.text++;
+ ctx->t_ctx.y -= 8.0 + style->font->size;
} else {
- if (ctx->y < MARGIN_BOTTOM) {
- if (!pdf_page_close_then_add(ctx, NUS_ROMAN)) {
+ if (ctx->t_ctx.y < MARGIN_BOTTOM) {
+ if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUS_ROMAN)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx->content->pages[ctx->page]->texts;
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
}
end_of_title_x = width;
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(entry->title);
- (*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);
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(entry->title);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ width = text_width(ctx, entry->title, style);
if (width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
- (*texts)[ctx->text]->width = width;
- ctx->text++;
+ (*texts)[ctx->t_ctx.text]->width = width;
+ ctx->t_ctx.text++;
sprintf((char *)&page_no, "%d", entry->page_index+1);
- page_no_width = text_width(page_no, style);
+ page_no_width = text_width(ctx, page_no, style);
if (page_no_width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
@@ -2207,130 +2024,348 @@ pdf_texts_add_toc_entry(
LOG_DEBUG("toc_dots_create failed.");
return false;
}
- dots_width = text_width(dots, style);
+ dots_width = text_width(ctx, dots, style);
if (dots_width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(dots);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = dots_width;
- ctx->text++;
-
- *texts = erealloc(*texts, (ctx->text+1) * sizeof(struct PDFText *));
- (*texts)[ctx->text] = pdf_text_new();
- (*texts)[ctx->text]->text = strdup(page_no);
- (*texts)[ctx->text]->style = cho_style_copy(style);
- (*texts)[ctx->text]->x = page_no_x;
- (*texts)[ctx->text]->y = ctx->y;
- (*texts)[ctx->text]->width = page_no_width;
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(dots);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ (*texts)[ctx->t_ctx.text]->width = dots_width;
+ ctx->t_ctx.text++;
+
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = pdf_text_new();
+ (*texts)[ctx->t_ctx.text]->text = strdup(page_no);
+ (*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
+ (*texts)[ctx->t_ctx.text]->x = page_no_x;
+ (*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
+ (*texts)[ctx->t_ctx.text]->width = page_no_width;
if (!annot_page_link_add(ctx, entry, toc_page_count, 1, style->font->size)) {
LOG_DEBUG("annot_page_link_add");
return false;
}
- ctx->text++;
- ctx->y -= 8.0 + style->font->size;
+ ctx->t_ctx.text++;
+ ctx->t_ctx.y -= 8.0 + style->font->size;
+ }
+ return true;
+}
+
+static bool
+pdf_texts_add_lyrics(
+ struct PDFContext *ctx,
+ struct ChoLineItem *item,
+ int i
+)
+{
+ struct PDFText ***texts;
+ struct SpaceNeeded **sp;
+ double width;
+ int t = 0;
+ int c;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ *texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->b_ctx.text] = pdf_text_new();
+ if (!ctx->b_ctx.spaces) {
+ (*texts)[ctx->b_ctx.text]->text = strdup(item->u.text->text);
+ (*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
+ (*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
+ (*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
+ width = text_width(ctx, item->u.text->text, item->u.text->style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ (*texts)[ctx->b_ctx.text]->width = width;
+ if (item->u.text->style->href) {
+ if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ ctx->b_ctx.x += width;
+ if ((*texts)[ctx->b_ctx.text]->style->font->size > ctx->b_ctx.biggest_font_size) {
+ ctx->b_ctx.biggest_font_size = (*texts)[ctx->b_ctx.text]->style->font->size;
+ }
+ ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
+ ctx->b_ctx.text++;
+ return true;
+ }
+ for (c = 0; item->u.text->text[c]; c++) {
+ (*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
+ (*texts)[ctx->b_ctx.text]->text[t] = item->u.text->text[c];
+ t++;
+ for (sp = ctx->b_ctx.spaces; *sp; sp++) {
+ if ((*sp)->line_item_index == i && (*sp)->text_index == c) {
+ size_t len = grapheme_next_character_break_utf8(&item->u.text->text[c], 10);
+ size_t i;
+ for (i = 0; i<len-1; i++, t++) {
+ c++;
+ (*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
+ (*texts)[ctx->b_ctx.text]->text[t] = item->u.text->text[c];
+ }
+ (*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
+ (*texts)[ctx->b_ctx.text]->text[t] = 0;
+ (*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
+ (*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
+ (*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
+ width = text_width(ctx, (*texts)[ctx->b_ctx.text]->text, item->u.text->style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ (*texts)[ctx->b_ctx.text]->width = width;
+ if (item->u.text->style->href) {
+ if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ ctx->b_ctx.x += width;
+ ctx->b_ctx.x += (*sp)->amount;
+ t = 0;
+ ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
+ ctx->b_ctx.text++;
+ *texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->b_ctx.text] = pdf_text_new();
+ }
+ }
+ }
+ (*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
+ (*texts)[ctx->b_ctx.text]->text[t] = 0;
+ (*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
+ (*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
+ (*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
+ width = text_width(ctx, (*texts)[ctx->b_ctx.text]->text, item->u.text->style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ (*texts)[ctx->b_ctx.text]->width = width;
+ if (item->u.text->style->href) {
+ if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ ctx->b_ctx.x += width;
+ if ((*texts)[ctx->b_ctx.text]->style->font->size > ctx->b_ctx.biggest_font_size) {
+ ctx->b_ctx.biggest_font_size = (*texts)[ctx->b_ctx.text]->style->font->size;
+ }
+ ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
+ ctx->b_ctx.text++;
+ return true;
+}
+
+static bool
+pdf_texts_add_text(
+ struct PDFContext *ctx,
+ struct PDFContentContext *c_ctx,
+ const char *text,
+ struct ChoStyle *style,
+ enum Alignment align,
+ enum NumeralSystem numeral_system
+)
+{
+ struct PDFText ***texts;
+ char str[strlen(text)+1];
+ double width;
+ int index;
+ strcpy((char *)&str, text);
+ texts = &c_ctx->content->pages[c_ctx->page]->texts;
+ width = text_width(ctx, text, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ if (width > LINE_WIDTH) {
+ char *t = (char *)&str;
+ while (width > LINE_WIDTH) {
+ if (c_ctx->y < c_ctx->margin_bottom) {
+ if (!pdf_page_close_then_add(ctx, c_ctx, numeral_system)) {
+ LOG_DEBUG("pdf_page_close_then_add failed.");
+ return false;
+ }
+ texts = &c_ctx->content->pages[c_ctx->page]->texts;
+ }
+ index = text_find_fitting(ctx, t, style, 0.0, LINE_WIDTH);
+ if (index == EMPTY_INT) {
+ LOG_DEBUG("text_find_fitting failed.");
+ return false;
+ }
+ t[index] = 0;
+ width = text_width(ctx, t, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ c_ctx->x = calc_x(width, align);
+ *texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[c_ctx->text] = pdf_text_new();
+ (*texts)[c_ctx->text]->text = strdup(t);
+ (*texts)[c_ctx->text]->style = cho_style_copy(style);
+ (*texts)[c_ctx->text]->x = c_ctx->x;
+ (*texts)[c_ctx->text]->y = c_ctx->y;
+ (*texts)[c_ctx->text]->width = width;
+ if (style->href) {
+ if (!annot_url_link_add(ctx, c_ctx, style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ c_ctx->text++;
+ c_ctx->y -= 8.0 + style->font->size;
+ t += index+1;
+ width = text_width(ctx, t, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ }
+ width = text_width(ctx, t, style);
+ if (width == ERROR) {
+ LOG_DEBUG("text_width failed.");
+ return false;
+ }
+ c_ctx->x = calc_x(width, align);
+ *texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[c_ctx->text] = pdf_text_new();
+ (*texts)[c_ctx->text]->text = strdup(t);
+ (*texts)[c_ctx->text]->style = cho_style_copy(style);
+ (*texts)[c_ctx->text]->x = c_ctx->x;
+ (*texts)[c_ctx->text]->y = c_ctx->y;
+ (*texts)[c_ctx->text]->width = width;
+ if (style->href) {
+ if (!annot_url_link_add(ctx, c_ctx, style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ c_ctx->text++;
+ c_ctx->y -= 8.0 + style->font->size;
+ } else {
+ if (c_ctx->y < c_ctx->margin_bottom) {
+ if (!pdf_page_close_then_add(ctx, c_ctx, numeral_system)) {
+ LOG_DEBUG("pdf_page_close_then_add failed.");
+ return false;
+ }
+ texts = &c_ctx->content->pages[c_ctx->page]->texts;
+ }
+ c_ctx->x = calc_x(width, align);
+ *texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
+ (*texts)[c_ctx->text] = pdf_text_new();
+ (*texts)[c_ctx->text]->text = strdup(text);
+ (*texts)[c_ctx->text]->style = cho_style_copy(style);
+ (*texts)[c_ctx->text]->x = c_ctx->x;
+ (*texts)[c_ctx->text]->y = c_ctx->y;
+ (*texts)[c_ctx->text]->width = width;
+ if (style->href) {
+ if (!annot_url_link_add(ctx, c_ctx, style, width)) {
+ LOG_DEBUG("annot_url_link_add failed.");
+ return false;
+ }
+ }
+ c_ctx->text++;
+ c_ctx->y -= 8.0 + style->font->size;
}
return true;
}
static bool
pdf_toc_create(
- struct PDFContent **toc_content,
- struct PDFContent *pdf_content,
- struct Config *config
+ struct PDFContext *ctx,
+ struct PDFContent *pdf_body,
+ struct PDFContent **out
)
{
double max_song_title_width, dot_width;
int toc_page_count;
- struct PDFContext ctx;
struct PDFText ***texts;
struct ChoStyle *toc_style, *title_style;
struct TocEntry **toc;
- pdf_context_init(&ctx);
- ctx.content = pdf_content_new();
- ctx.content->pages = emalloc(sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = pdf_page_new();
- texts = &ctx.content->pages[ctx.page]->texts;
- if (config->output->page_no->show) {
- if (!pdf_page_add_page_no(&ctx, NUS_ROMAN)) {
+ pdf_content_context_init(&ctx->t_ctx);
+ ctx->t_ctx.content = pdf_content_new();
+ ctx->t_ctx.content->pages = emalloc(sizeof(struct PDFPage *));
+ ctx->t_ctx.content->pages[ctx->t_ctx.page] = pdf_page_new(ctx);
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
+ if (ctx->config->output->page_no->show) {
+ if (!pdf_page_add_page_no(ctx, &ctx->t_ctx, NUS_ROMAN)) {
LOG_DEBUG("pdf_page_add_page_no failed.");
return false;
}
}
- toc_style = config->output->styles[TT_TOC];
- toc = pdf_content->toc;
+ toc_style = ctx->config->output->styles[TT_TOC];
+ toc = pdf_body->toc;
max_song_title_width = LINE_WIDTH * 0.85;
- toc_page_count = pdf_toc_page_count(toc, toc_style, max_song_title_width);
+ toc_page_count = pdf_toc_page_count(ctx, toc, toc_style, max_song_title_width);
if (toc_page_count == -1) {
LOG_DEBUG("pdf_toc_page_count failed.");
return false;
}
- title_style = config->output->styles[TT_TOC_TITLE];
- if (!pdf_texts_add_text(&ctx, config->output->toc->title, title_style, A_CENTER, NUS_ROMAN)) {
+ title_style = ctx->config->output->styles[TT_TOC_TITLE];
+ if (!pdf_texts_add_text(ctx, &ctx->t_ctx, ctx->config->output->toc->title, title_style, A_CENTER, NUS_ROMAN)) {
LOG_DEBUG("pdf_texts_add_text(toctitle) failed.");
return false;
}
- ctx.y -= 30.0;
- dot_width = text_width(".", toc_style);
+ ctx->t_ctx.y -= 30.0;
+ dot_width = text_width(ctx, ".", toc_style);
if (dot_width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
for (; *toc; toc++) {
- if (!pdf_texts_add_toc_entry(&ctx, *toc, toc_style, max_song_title_width, toc_page_count, dot_width)) {
+ if (!pdf_texts_add_toc_entry(ctx, *toc, toc_style, max_song_title_width, toc_page_count, dot_width)) {
LOG_DEBUG("pdf_texts_add_toc_entry failed.");
return false;
}
}
- texts = &ctx.content->pages[ctx.page]->texts;
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = NULL;
- ctx.page++;
- ctx.content->pages = erealloc(ctx.content->pages, (ctx.page+1) * sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = NULL;
- *toc_content = ctx.content;
+ texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
+ *texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->t_ctx.text] = NULL;
+ ctx->t_ctx.page++;
+ ctx->t_ctx.content->pages = erealloc(ctx->t_ctx.content->pages, (ctx->t_ctx.page+1) * sizeof(struct PDFPage *));
+ ctx->t_ctx.content->pages[ctx->t_ctx.page] = NULL;
+ *out = ctx->t_ctx.content;
return true;
}
static bool
-pdf_content_create(
- struct PDFContent **out,
+pdf_body_create(
+ struct PDFContext *ctx,
struct ChoSong **songs,
- struct Config *config,
- struct Obj **img_objs
+ struct Obj **img_objs,
+ struct PDFContent **out
)
{
struct ChoSection **se;
struct ChoLine **li;
struct PDFText ***texts;
struct PDFImage ***imgs;
- struct PDFContext ctx;
struct ChordDiagram ***diagrams, **dgrams, **d;
- char *metadata;
struct ChoStyle *metadata_style;
- bool show_diagram = config->output->diagram->show;
- bool start_song_on_new_page = config->output->start_song_on_new_page;
+ char *metadata;
+ bool show_diagram = ctx->config->output->diagram->show;
+ bool start_song_on_new_page = ctx->config->output->start_song_on_new_page;
double width, height;
- pdf_context_init(&ctx);
+ pdf_content_context_init(&ctx->b_ctx);
if (show_diagram) {
- 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();
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
- if (config->output->page_no->show) {
- if (!pdf_page_add_page_no(&ctx, NUS_WESTERN_ARABIC)) {
+ ctx->b_ctx.margin_bottom = 150.0;
+ }
+ ctx->b_ctx.content = pdf_content_new();
+ ctx->b_ctx.content->pages = emalloc(sizeof(struct PDFPage *));
+ ctx->b_ctx.content->pages[ctx->b_ctx.page] = pdf_page_new(ctx);
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
+ if (ctx->config->output->page_no->show) {
+ if (!pdf_page_add_page_no(ctx, &ctx->b_ctx, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_page_add_page_no failed.");
return false;
}
@@ -2345,51 +2380,51 @@ pdf_content_create(
}
if (chords) {
qsort(chords, cho_chord_count(chords), sizeof(struct ChoChord *), cho_chord_compare);
- dgrams = chord_diagrams_create(config, &chords, songs[s]->diagrams);
+ dgrams = chord_diagrams_create(ctx->config, &chords, songs[s]->diagrams);
for (d = dgrams; *d; d++) {
- *diagrams = erealloc(*diagrams, (ctx.diagram+1) * sizeof(struct ChordDiagram *));
- (*diagrams)[ctx.diagram] = *d;
- ctx.diagram++;
+ *diagrams = erealloc(*diagrams, (ctx->b_ctx.diagram+1) * sizeof(struct ChordDiagram *));
+ (*diagrams)[ctx->b_ctx.diagram] = *d;
+ ctx->b_ctx.diagram++;
}
free(dgrams);
}
cho_chords_free(chords);
}
- if (!cho_metadata_value(songs[s]->metadata, "title", config->metadata_separator, &metadata, &metadata_style)) {
+ if (!cho_metadata_value(songs[s]->metadata, "title", ctx->config->metadata_separator, &metadata, &metadata_style)) {
LOG_DEBUG("cho_metadata_value failed.");
return false;
}
- ctx.content->toc = erealloc(ctx.content->toc, (ctx.toc_entry+1) * sizeof(struct TocEntry *));
- ctx.content->toc[ctx.toc_entry] = emalloc(sizeof(struct TocEntry));
- ctx.content->toc[ctx.toc_entry]->title = strdup(metadata);
- ctx.content->toc[ctx.toc_entry]->page_index = ctx.page;
- ctx.content->toc[ctx.toc_entry]->page_y = ctx.y;
- ctx.toc_entry++;
- if (!pdf_texts_add_text(&ctx, metadata, metadata_style, A_CENTER, NUS_WESTERN_ARABIC)) {
+ ctx->b_ctx.content->toc = erealloc(ctx->b_ctx.content->toc, (ctx->b_ctx.toc_entry+1) * sizeof(struct TocEntry *));
+ ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry] = emalloc(sizeof(struct TocEntry));
+ ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->title = strdup(metadata);
+ ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->page_index = ctx->b_ctx.page;
+ ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->page_y = ctx->b_ctx.y;
+ ctx->b_ctx.toc_entry++;
+ if (!pdf_texts_add_text(ctx, &ctx->b_ctx, metadata, metadata_style, A_CENTER, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_texts_add_text(title) failed.");
return false;
}
free(metadata);
- if (cho_metadata_value(songs[s]->metadata, "subtitle", config->metadata_separator, &metadata, &metadata_style)) {
- if (!pdf_texts_add_text(&ctx, metadata, metadata_style, A_CENTER, NUS_WESTERN_ARABIC)) {
+ if (cho_metadata_value(songs[s]->metadata, "subtitle", ctx->config->metadata_separator, &metadata, &metadata_style)) {
+ if (!pdf_texts_add_text(ctx, &ctx->b_ctx, metadata, metadata_style, A_CENTER, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_texts_add_text(subtitle) failed.");
return false;
}
free(metadata);
}
- 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;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
+ ctx->b_ctx.y -= 30.0;
for (se = songs[s]->sections; *se; se++) {
if ((*se)->label) {
- if (!pdf_texts_add_text(&ctx, (*se)->label->text, (*se)->label->style, A_LEFT, NUS_WESTERN_ARABIC)) {
+ if (!pdf_texts_add_text(ctx, &ctx->b_ctx, (*se)->label->text, (*se)->label->style, A_LEFT, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_texts_add_text(label) failed.");
return false;
}
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
}
for (li = (*se)->lines; *li; li++) {
int item_index;
@@ -2398,16 +2433,16 @@ pdf_content_create(
struct ChoLineItemAbove **left_aboves = (*li)->text_above;
struct ChoLineItem **left_items = (*li)->items;
while (*left_aboves || *left_items) {
- ctx.consumed_lyrics = 0;
- ctx.biggest_font_size = 0.0;
- ctx.prev_added_space = 0.0;
+ ctx->b_ctx.consumed_lyrics = 0;
+ ctx->b_ctx.biggest_font_size = 0.0;
+ ctx->b_ctx.prev_added_space = 0.0;
char *string;
struct ChoStyle *style;
- if (!calc_space_between_text_above(left_items, left_aboves, img_objs, &ctx.spaces)) {
+ if (!calc_space_between_text_above(ctx, left_items, left_aboves, img_objs, &ctx->b_ctx.spaces)) {
LOG_DEBUG("calc_space_between_text_above failed.");
return false;
}
- pos = items_find_position_to_break_line(left_items, ctx.spaces, img_objs);
+ pos = items_find_position_to_break_line(ctx, left_items, ctx->b_ctx.spaces, img_objs);
if (pos->line_item_index == -1) {
item_index = 10000;
text_above_index = 10000;
@@ -2425,23 +2460,23 @@ pdf_content_create(
bool text_above_exist;
int i;
for (i = 0; left_aboves[i] && i<text_above_index; i++) {
- width = line_width_until_text_above(left_items, left_aboves[i], img_objs, NULL);
+ width = line_width_until_text_above(ctx, left_items, left_aboves[i], img_objs, NULL);
if (width == ERROR) {
- LOG_DEBUG("line_width_until_text_aboave failed.");
+ LOG_DEBUG("line_width_until_text_above failed.");
return false;
}
- ctx.x = MARGIN_HORIZONTAL + width + ctx.prev_added_space;
+ ctx->b_ctx.x = MARGIN_HORIZONTAL + width + ctx->b_ctx.prev_added_space;
struct SpaceNeeded **sp;
- for (sp = ctx.spaces; *sp; sp++) {
+ for (sp = ctx->b_ctx.spaces; *sp; sp++) {
if ((*sp)->text_above_index == i) {
- ctx.x += (*sp)->amount;
- ctx.prev_added_space += (*sp)->amount;
+ ctx->b_ctx.x += (*sp)->amount;
+ ctx->b_ctx.prev_added_space += (*sp)->amount;
}
}
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = pdf_text_new();
- (*texts)[ctx.text]->x = ctx.x;
- (*texts)[ctx.text]->y = ctx.y;
+ *texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->b_ctx.text] = pdf_text_new();
+ (*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
+ (*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
if (left_aboves[i]->is_chord) {
string = cho_chord_name_generate(left_aboves[i]->u.chord);
style = cho_style_copy(left_aboves[i]->u.chord->style);
@@ -2449,25 +2484,25 @@ pdf_content_create(
string = strdup(left_aboves[i]->u.annot->text);
style = cho_style_copy(left_aboves[i]->u.annot->style);
}
- (*texts)[ctx.text]->text = string;
- (*texts)[ctx.text]->style = style;
- (*texts)[ctx.text]->width = text_width(string, style);
- if ((*texts)[ctx.text]->width == ERROR) {
+ (*texts)[ctx->b_ctx.text]->text = string;
+ (*texts)[ctx->b_ctx.text]->style = style;
+ (*texts)[ctx->b_ctx.text]->width = text_width(ctx, string, style);
+ if ((*texts)[ctx->b_ctx.text]->width == ERROR) {
LOG_DEBUG("text_width failed.");
return false;
}
if (style->href) {
- if (!annot_url_link_add(&ctx, style, (*texts)[ctx.text]->width)) {
+ if (!annot_url_link_add(ctx, &ctx->b_ctx, style, (*texts)[ctx->b_ctx.text]->width)) {
LOG_DEBUG("annot_url_link_add failed.");
return false;
}
}
- if (style->font->size > ctx.biggest_font_size) {
- ctx.biggest_font_size = style->font->size;
+ if (style->font->size > ctx->b_ctx.biggest_font_size) {
+ ctx->b_ctx.biggest_font_size = style->font->size;
}
- ctx.text++;
+ ctx->b_ctx.text++;
}
- height = images_find_biggest_height(left_items, pos->line_item_index, img_objs);
+ height = images_find_biggest_height(ctx, left_items, pos->line_item_index, img_objs);
if (height == ERROR) {
LOG_DEBUG("images_find_biggest_height failed.");
return false;
@@ -2475,88 +2510,88 @@ pdf_content_create(
text_above_exist = i > 0;
if (text_above_exist) {
left_aboves += i;
- if (height > 2.0 + ctx.biggest_font_size) {
- ctx.y -= height;
+ if (height > 2.0 + ctx->b_ctx.biggest_font_size) {
+ ctx->b_ctx.y -= height;
} else {
- ctx.y -= 2.0 + ctx.biggest_font_size;
+ ctx->b_ctx.y -= 2.0 + ctx->b_ctx.biggest_font_size;
}
} else {
if (height > 0.0) {
- ctx.y -= height;
+ ctx->b_ctx.y -= height;
}
}
- if (ctx.y < ctx.margin_bottom) {
+ if (ctx->b_ctx.y < ctx->b_ctx.margin_bottom) {
struct PDFText **tmp = NULL;
int tm = 0;
- ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
+ ctx->b_ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
if (text_above_exist) {
/* INFO: chords/annotations and their corresponding lyrics won't be splitted */
int p;
- double prev_y = (*texts)[ctx.text-1]->y;
- for (p = ctx.text-1; prev_y == (*texts)[p]->y; p--) {
- (*texts)[p]->y = ctx.y;
+ double prev_y = (*texts)[ctx->b_ctx.text-1]->y;
+ for (p = ctx->b_ctx.text-1; prev_y == (*texts)[p]->y; p--) {
+ (*texts)[p]->y = ctx->b_ctx.y;
tmp = erealloc(tmp, (tm+1) * sizeof(struct PDFText *));
tmp[tm] = (*texts)[p];
tm++;
- *texts = erealloc(*texts, (--ctx.text) * sizeof(struct PDFText *));
+ *texts = erealloc(*texts, (--ctx->b_ctx.text) * sizeof(struct PDFText *));
}
}
- if (!pdf_page_close_then_add(&ctx, NUS_WESTERN_ARABIC)) {
+ if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
if (text_above_exist) {
for (int i=0; i<tm; i++) {
- *texts = erealloc(*texts, (ctx.text+1) * sizeof(struct PDFText *));
- (*texts)[ctx.text] = tmp[i];
- ctx.text++;
+ *texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->b_ctx.text] = tmp[i];
+ ctx->b_ctx.text++;
}
free(tmp);
}
if (text_above_exist) {
- if (height > 2.0 + ctx.biggest_font_size) {
- ctx.y -= height;
+ if (height > 2.0 + ctx->b_ctx.biggest_font_size) {
+ ctx->b_ctx.y -= height;
} else {
- ctx.y -= 2.0 + ctx.biggest_font_size;
+ ctx->b_ctx.y -= 2.0 + ctx->b_ctx.biggest_font_size;
}
} else {
- ctx.y -= height;
+ ctx->b_ctx.y -= height;
}
}
- ctx.biggest_font_size = 0.0;
- ctx.x = MARGIN_HORIZONTAL;
+ ctx->b_ctx.biggest_font_size = 0.0;
+ ctx->b_ctx.x = MARGIN_HORIZONTAL;
i = 0;
while (*left_items && i < item_index) {
if ((*left_items)->is_text) {
- if (!pdf_texts_add_lyrics(*left_items, &ctx, i)) {
+ if (!pdf_texts_add_lyrics(ctx, *left_items, i)) {
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;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
} else {
- *imgs = erealloc(*imgs, (ctx.image+1) * sizeof(struct PDFImage *));
- (*imgs)[ctx.image] = pdf_image_new();
- (*imgs)[ctx.image]->name = image_name((*left_items)->u.image);
- if (!(*imgs)[ctx.image]->name) {
+ *imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
+ (*imgs)[ctx->b_ctx.image] = pdf_image_new();
+ (*imgs)[ctx->b_ctx.image]->name = image_name(ctx, (*left_items)->u.image);
+ if (!(*imgs)[ctx->b_ctx.image]->name) {
LOG_DEBUG("image_name failed.");
return false;
}
- (*imgs)[ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx.image]->name);
- if (!(*imgs)[ctx.image]->obj) {
+ (*imgs)[ctx->b_ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx->b_ctx.image]->name);
+ if (!(*imgs)[ctx->b_ctx.image]->obj) {
LOG_DEBUG("objs_get_obj failed.");
return false;
}
- (*imgs)[ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx.image]->obj);
- (*imgs)[ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx.image]->obj);
- (*imgs)[ctx.image]->x = ctx.x;
- (*imgs)[ctx.image]->y = ctx.y;
- ctx.x += (*imgs)[ctx.image]->width;
- ctx.image++;
+ (*imgs)[ctx->b_ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
+ (*imgs)[ctx->b_ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
+ (*imgs)[ctx->b_ctx.image]->x = ctx->b_ctx.x;
+ (*imgs)[ctx->b_ctx.image]->y = ctx->b_ctx.y;
+ ctx->b_ctx.x += (*imgs)[ctx->b_ctx.image]->width;
+ ctx->b_ctx.image++;
}
i++;
left_items++;
@@ -2566,99 +2601,99 @@ pdf_content_create(
char *tmp;
(*left_items)->u.text->text[pos->text_index] = 0;
tmp = strdup(&(*left_items)->u.text->text[pos->text_index+1]);
- if (!pdf_texts_add_lyrics(*left_items, &ctx, i)) {
+ if (!pdf_texts_add_lyrics(ctx, *left_items, i)) {
LOG_DEBUG("pdf_texts_add_lyrics failed.");
return false;
}
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;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
}
} else
if (pos->line_item_index != -1 && pos->text_index == -1) {
if (!(*left_items)->is_text) {
- *imgs = erealloc(*imgs, (ctx.image+1) * sizeof(struct PDFImage *));
- (*imgs)[ctx.image] = pdf_image_new();
- (*imgs)[ctx.image]->name = image_name((*left_items)->u.image);
- if (!(*imgs)[ctx.image]->name) {
+ *imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
+ (*imgs)[ctx->b_ctx.image] = pdf_image_new();
+ (*imgs)[ctx->b_ctx.image]->name = image_name(ctx, (*left_items)->u.image);
+ if (!(*imgs)[ctx->b_ctx.image]->name) {
LOG_DEBUG("image_name failed.");
return false;
}
- (*imgs)[ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx.image]->name);
- if (!(*imgs)[ctx.image]->obj) {
+ (*imgs)[ctx->b_ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx->b_ctx.image]->name);
+ if (!(*imgs)[ctx->b_ctx.image]->obj) {
LOG_DEBUG("objs_get_obj failed.");
return false;
}
- (*imgs)[ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx.image]->obj);
- (*imgs)[ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx.image]->obj);
- (*imgs)[ctx.image]->x = ctx.x;
- (*imgs)[ctx.image]->y = ctx.y;
- ctx.image++;
+ (*imgs)[ctx->b_ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
+ (*imgs)[ctx->b_ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
+ (*imgs)[ctx->b_ctx.image]->x = ctx->b_ctx.x;
+ (*imgs)[ctx->b_ctx.image]->y = ctx->b_ctx.y;
+ ctx->b_ctx.image++;
}
left_items++;
}
- ctx.y -= 8.0 + ctx.biggest_font_size;
- if (ctx.y < ctx.margin_bottom) {
- if (!pdf_page_close_then_add(&ctx, NUS_WESTERN_ARABIC)) {
+ ctx->b_ctx.y -= 8.0 + ctx->b_ctx.biggest_font_size;
+ if (ctx->b_ctx.y < ctx->b_ctx.margin_bottom) {
+ if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
}
- spaces_free(ctx.spaces);
- ctx.spaces = NULL;
+ spaces_free(ctx->b_ctx.spaces);
+ ctx->b_ctx.spaces = NULL;
free(pos);
pos = NULL;
- text_above_update_positions(left_aboves, ctx.consumed_lyrics);
+ text_above_update_positions(left_aboves, ctx->b_ctx.consumed_lyrics);
}
if ((*li)->btype == BT_PAGE) {
- if (!pdf_page_close_then_add(&ctx, NUS_WESTERN_ARABIC)) {
+ if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
}
}
- ctx.y -= SECTION_GAP_WIDTH;
+ ctx->b_ctx.y -= SECTION_GAP_WIDTH;
}
if (start_song_on_new_page) {
- if (!pdf_page_close_then_add(&ctx, NUS_WESTERN_ARABIC)) {
+ if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUS_WESTERN_ARABIC)) {
LOG_DEBUG("pdf_page_close_then_add failed.");
return false;
}
- texts = &ctx.content->pages[ctx.page]->texts;
- imgs = &ctx.content->pages[ctx.page]->images;
- diagrams = &ctx.content->pages[ctx.page]->diagrams;
+ texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
+ imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
+ diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
}
}
- *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;
+ *texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
+ (*texts)[ctx->b_ctx.text] = NULL;
+ *imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
+ (*imgs)[ctx->b_ctx.image] = NULL;
+ *diagrams = erealloc(*diagrams, (ctx->b_ctx.diagram+1) * sizeof(struct ChordDiagram *));
+ (*diagrams)[ctx->b_ctx.diagram] = NULL;
if (start_song_on_new_page) {
- pdf_page_free(ctx.content->pages[ctx.page]);
- ctx.content->pages[ctx.page] = NULL;
+ pdf_page_free(ctx->b_ctx.content->pages[ctx->b_ctx.page]);
+ ctx->b_ctx.content->pages[ctx->b_ctx.page] = NULL;
} else {
- ctx.page++;
- ctx.content->pages = erealloc(ctx.content->pages, (ctx.page+1) * sizeof(struct PDFPage *));
- ctx.content->pages[ctx.page] = NULL;
+ ctx->b_ctx.page++;
+ ctx->b_ctx.content->pages = erealloc(ctx->b_ctx.content->pages, (ctx->b_ctx.page+1) * sizeof(struct PDFPage *));
+ ctx->b_ctx.content->pages[ctx->b_ctx.page] = NULL;
}
- ctx.content->toc = erealloc(ctx.content->toc, (ctx.toc_entry+1) * sizeof(struct TocEntry *));
- ctx.content->toc[ctx.toc_entry] = NULL;
- *out = ctx.content;
+ ctx->b_ctx.content->toc = erealloc(ctx->b_ctx.content->toc, (ctx->b_ctx.toc_entry+1) * sizeof(struct TocEntry *));
+ ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry] = NULL;
+ *out = ctx->b_ctx.content;
return true;
}
static bool
-pdf_toc_render(struct PDFContent *content, pdfio_file_t *file)
+pdf_toc_render(struct PDFContext *ctx, struct PDFContent *content)
{
struct PDFPage **pages;
struct PDFText **texts;
@@ -2666,14 +2701,14 @@ pdf_toc_render(struct PDFContent *content, pdfio_file_t *file)
pages = content->pages;
int p;
for (p = 0; pages[p]; p++) {
- g_current_page_index = p;
- stream = pdf_page_create(file, NULL, pages[p]->annots);
+ ctx->current_page_index = p;
+ stream = pdf_page_create(ctx, NULL, pages[p]->annots);
if (!stream) {
LOG_DEBUG("pdf_page_create failed.");
return false;
}
for (texts = pages[p]->texts; *texts; texts++) {
- if (!pdf_text_show(stream, *texts)) {
+ if (!pdf_text_show(ctx, stream, *texts)) {
LOG_DEBUG("pdf_text_show failed.");
return false;
}
@@ -2687,7 +2722,7 @@ pdf_toc_render(struct PDFContent *content, pdfio_file_t *file)
}
static bool
-pdf_content_render(struct PDFContent *content, pdfio_file_t *file)
+pdf_body_render(struct PDFContext *ctx, struct PDFContent *content)
{
int p;
struct PDFPage **pages;
@@ -2696,14 +2731,14 @@ pdf_content_render(struct PDFContent *content, pdfio_file_t *file)
pdfio_stream_t *stream;
pages = content->pages;
for (p = 0; pages[p]; p++) {
- g_current_page_index = p;
- stream = pdf_page_create(file, pages[p]->images, pages[p]->annots);
+ ctx->current_page_index = p;
+ stream = pdf_page_create(ctx, pages[p]->images, pages[p]->annots);
if (!stream) {
LOG_DEBUG("pdf_page_create failed.");
return false;
}
for (texts = pages[p]->texts; *texts; texts++) {
- if (!pdf_text_show(stream, *texts)) {
+ if (!pdf_text_show(ctx, stream, *texts)) {
LOG_DEBUG("pdf_text_show failed.");
return false;
}
@@ -2732,7 +2767,7 @@ pdf_content_render(struct PDFContent *content, pdfio_file_t *file)
/* TODO: Handle line break when too long */
for (d = pages[p]->diagrams; *d; d++) {
if ((*d)->show) {
- if (!chord_diagram_draw(stream, *d, x, y, size)) {
+ if (!chord_diagram_draw(ctx, stream, *d, x, y, size)) {
LOG_DEBUG("chord_diagram_draw failed.");
return false;
}
@@ -2758,79 +2793,77 @@ out_pdf_create(
{
struct Font **needed_fonts;
struct Obj **img_objs = NULL;
- struct PDFContent *pdf_content = NULL;
- struct PDFContent *toc_content = NULL;
+ struct PDFContent *pdf_body = NULL;
+ struct PDFContent *pdf_toc = NULL;
+ struct PDFContext ctx;
pdfio_rect_t media_box_a4 = { 0.0, 0.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
pdfio_rect_t crop_box = { 0.0, 0.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
char *dirpath, *pdf_filepath;
- g_config = config;
-
- memset(&g_current_font_name, 0, sizeof(g_current_font_name));
- memset(&g_cho_dirpath, 0, PATH_MAX);
+ ctx.fonts = NULL;
+ ctx.config = config;
+ ctx.current_page_index = 0;
+ ctx.current_font_size = 0.0;
+ memset(&ctx.cho_dirpath, 0, PATH_MAX);
+ memset(&ctx.current_font_name, 0, 200);
if (cho_filepath) {
dirpath = filepath_dirname(cho_filepath);
} else {
dirpath = getcwd(NULL, 0);
}
- strcpy((char *)&g_cho_dirpath, dirpath);
+ strcpy((char *)&ctx.cho_dirpath, dirpath);
free(dirpath);
- pdf_filepath = pdf_filepath_create(songs, cho_filepath, output_folder_or_file);
+ pdf_filepath = pdf_filepath_create(&ctx, songs, cho_filepath, output_folder_or_file);
if (!pdf_filepath) {
LOG_DEBUG("pdf_filepath_create failed.");
return NULL;
}
- g_pdf_file = pdfioFileCreate(pdf_filepath, "2.0", &media_box_a4, &crop_box, NULL, NULL);
- if (!g_pdf_file) {
+ ctx.pdf_file = pdfioFileCreate(pdf_filepath, "2.0", &media_box_a4, &crop_box, NULL, NULL);
+ if (!ctx.pdf_file) {
LOG_DEBUG("pdfioFileCreate failed.");
return NULL;
}
- if (!pdf_set_title(g_pdf_file, songs)) {
+ if (!pdf_set_title(&ctx, songs)) {
LOG_DEBUG("pdf_set_title failed.");
goto CLEAN;
}
- needed_fonts = fonts_get_all(songs, config);
- if (!pdf_load_fonts(needed_fonts, config)) {
+ needed_fonts = fonts_get_all(songs, ctx.config);
+ if (!pdf_load_fonts(&ctx, needed_fonts)) {
LOG_DEBUG("pdf_load_fonts failed.");
goto CLEAN;
}
cho_fonts_free(needed_fonts);
- if (!pdf_load_images(&img_objs, g_pdf_file, songs)) {
+ if (!pdf_load_images(&ctx, &img_objs, songs)) {
LOG_DEBUG("pdf_load_images failed.");
goto CLEAN;
}
- if (!pdf_content_create(&pdf_content, songs, config, img_objs)) {
- LOG_DEBUG("pdf_content_create failed.");
+ if (!pdf_body_create(&ctx, songs, img_objs, &pdf_body)) {
+ LOG_DEBUG("pdf_body_create failed.");
goto CLEAN;
}
- if (config->output->toc->show) {
- if (!pdf_toc_create(&toc_content, pdf_content, config)) {
+ if (ctx.config->output->toc->show) {
+ if (!pdf_toc_create(&ctx, pdf_body, &pdf_toc)) {
LOG_DEBUG("pdf_toc_create failed.");
goto CLEAN;
}
- if (!pdf_toc_render(toc_content, g_pdf_file)) {
+ if (!pdf_toc_render(&ctx, pdf_toc)) {
LOG_DEBUG("pdf_toc_render failed.");
goto CLEAN;
}
}
- if (!pdf_content_render(pdf_content, g_pdf_file)) {
- LOG_DEBUG("pdf_content_render failed.");
+ if (!pdf_body_render(&ctx, pdf_body)) {
+ LOG_DEBUG("pdf_body_render failed.");
goto CLEAN;
}
objs_free(img_objs);
- pdf_content_free(toc_content);
- pdf_content_free(pdf_content);
- if (!pdfioFileClose(g_pdf_file)) {
+ pdf_content_free(pdf_toc);
+ pdf_content_free(pdf_body);
+ if (!pdfioFileClose(ctx.pdf_file)) {
LOG_DEBUG("pdfioFileClose failed.");
goto CLEAN;
}
- g_pdf_file = NULL;
- objs_free(g_fonts);
- g_fonts = NULL;
- g_current_font_size = 0.0;
- g_current_page_index = 0;
- g_config = NULL;
+ objs_free(ctx.fonts);
return pdf_filepath;
CLEAN:
if (unlink(pdf_filepath)) {
diff --git a/src/out_pdf.h b/src/out_pdf.h
@@ -1,4 +1,5 @@
#include <pdfio.h>
+#include <linux/limits.h>
#include "core.h"
#include "chordpro.h"
@@ -81,7 +82,7 @@ struct SpaceNeeded {
double amount;
};
-struct PDFContext {
+struct PDFContentContext {
struct PDFContent *content;
double x;
double y;
@@ -97,5 +98,17 @@ struct PDFContext {
double margin_bottom;
};
+struct PDFContext {
+ struct Obj **fonts;
+ struct Config *config;
+ pdfio_file_t *pdf_file;
+ double current_font_size;
+ int current_page_index;
+ char cho_dirpath[PATH_MAX];
+ char current_font_name[200];
+ struct PDFContentContext t_ctx; // INFO: context for pdf_toc_create()
+ struct PDFContentContext b_ctx; // INFO: context for pdf_body_create()
+};
+
char *out_pdf_create(const char *cho_filename, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config);
-pdfio_obj_t *out_pdf_fnt_obj_get_by_name(const char *name);
+pdfio_obj_t *out_pdf_fnt_obj_get_by_name(struct PDFContext *ctx, const char *name);