lorid

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

out_pdf.c (82519B)


      1 #include <stdbool.h>
      2 #include <string.h>
      3 #include <unistd.h>
      4 #include <pdfio.h>
      5 #include <pdfio-content.h>
      6 #include <sys/stat.h>
      7 #include <errno.h>
      8 #include <fontconfig/fontconfig.h>
      9 #include <grapheme.h>
     10 #include <math.h>
     11 #include "core.h"
     12 #include "out_pdf.h"
     13 #include "chordpro.h"
     14 #include "config.h"
     15 #include "chord_diagram.h"
     16 
     17 static struct Obj *
     18 obj_new(void)
     19 {
     20 	struct Obj *obj = emalloc(sizeof(struct Obj));
     21 	obj->name = NULL;
     22 	obj->value = NULL;
     23 	return obj;
     24 }
     25 
     26 static void
     27 obj_free(struct Obj *obj)
     28 {
     29 	if (!obj) {
     30 		return;
     31 	}
     32 	free(obj->name);
     33 	free(obj);
     34 }
     35 
     36 static void
     37 objs_free(struct Obj **objs)
     38 {
     39 	if (!objs) {
     40 		return;
     41 	}
     42 	struct Obj **start = objs;
     43 	for (; *objs; objs++) {
     44 		obj_free(*objs);
     45 	}
     46 	free(start);
     47 }
     48 
     49 static pdfio_obj_t *
     50 objs_get_obj(struct Obj **objs, const char *name)
     51 {
     52 	if (!objs) {
     53 		return NULL;
     54 	}
     55 	struct Obj **o;
     56 	for (o = objs; *o; o++) {
     57 		if (!strcmp((*o)->name, name)) {
     58 			return (*o)->value;
     59 		}
     60 	}
     61 	return NULL;
     62 }
     63 
     64 static void
     65 objs_add_obj(struct Obj ***array, struct Obj *obj)
     66 {
     67 	if (!*array) {
     68 		*array = erealloc(*array, 2 * sizeof(struct Obj *));
     69 		(*array)[0] = obj;
     70 		(*array)[1] = NULL;
     71 	} else {
     72 		int a;
     73 		for (a = 0; (*array)[a]; a++);
     74 		*array = erealloc(*array, (a+2) * sizeof(struct Obj *));
     75 		(*array)[a] = obj;
     76 		(*array)[a+1] = NULL;
     77 	}
     78 }
     79 
     80 pdfio_obj_t *
     81 out_pdf_fnt_obj_get_by_name(struct PDFContext *ctx, const char *name)
     82 {
     83 	int i;
     84 	for (i = 0; ctx->fonts[i]; i++) {
     85 		if (!strcmp(ctx->fonts[i]->name, name)) {
     86 			return ctx->fonts[i]->value;
     87 		}
     88 	}
     89 	return NULL;
     90 }
     91 
     92 static char *
     93 fnt_name_create(struct Font *font)
     94 {
     95 	const char *c;
     96 	char *f;
     97 	char *family = str_normalize(font->family);
     98 	const char *style = cho_font_style_to_config_string(font->style);
     99 	const char *weight = cho_font_weight_to_config_string(font->weight);
    100 	size_t len = strlen(family) + strlen(style) + strlen(weight);
    101 	char *fnt_name = emalloc((len + 4) * sizeof(char));
    102 
    103 	f = fnt_name;
    104 	for (c = family; *c; c++, f++) {
    105 		*f = *c;
    106 	}
    107 	*f = '-';
    108 	f++;
    109 	for (c = style; *c; c++, f++) {
    110 		*f = *c;
    111 	}
    112 	*f = '-';
    113 	f++;
    114 	for (c = weight; *c; c++, f++) {
    115 		*f = *c;
    116 	}
    117 	*f = '\0';
    118 	free(family);
    119 	return fnt_name;
    120 }
    121 
    122 static bool
    123 fonts_add_if_not_in(struct Font ***array, struct Font *font)
    124 {
    125 	if (!*array) {
    126 		*array = erealloc(*array, 2 * sizeof(struct Font *));
    127 		(*array)[0] = font;
    128 		(*array)[1] = NULL;
    129 		return true;
    130 	} else {
    131 		int a;
    132 		for (a = 0; (*array)[a]; a++) {
    133 			if (
    134 				!strcmp((*array)[a]->family, font->family) &&
    135 				(*array)[a]->style == font->style &&
    136 				(*array)[a]->weight == font->weight
    137 			) {
    138 				return false;
    139 			}
    140 		}
    141 		*array = erealloc(*array, (a+2) * sizeof(struct Font *));
    142 		(*array)[a] = font;
    143 		(*array)[a+1] = NULL;
    144 		return true;
    145 	}
    146 }
    147 
    148 static struct Font **
    149 fonts_get_all(struct ChoSong **songs, struct Config *config)
    150 {
    151 	struct Font **fonts = NULL;
    152 	struct Font *font;
    153 	struct ChoSong **so;
    154 	struct ChoMetadata **m;
    155 	struct ChoSection **se;
    156 	struct ChoLine **li;
    157 	struct ChoLineItemAbove **above;
    158 	struct ChoLineItem **it;
    159 	struct ChoStyle *style;
    160 	bool added;
    161 	int i;
    162 
    163 	for (so = songs; *so; so++) {
    164 		for (i = 0; i < TEXT_TYPE_LENGTH; i++) {
    165 			if ((*so)->present_text_types[i]) {
    166 				font = cho_font_copy(config->output->styles[i]->font);
    167 				added = fonts_add_if_not_in(&fonts, font);
    168 				if (!added) {
    169 					cho_font_free(font);
    170 				}
    171 			}
    172 		}
    173 		for (m = (*so)->metadata; *m; m++) {
    174 			font = cho_font_copy((*m)->style->font);
    175 			added = fonts_add_if_not_in(&fonts, font);
    176 			if (!added) {
    177 				cho_font_free(font);
    178 			}
    179 		}
    180 		for (se = (*so)->sections; *se; se++) {
    181 			if ((*se)->label && (*se)->label->style->font->family) {
    182 				font = cho_font_copy((*se)->label->style->font);
    183 				added = fonts_add_if_not_in(&fonts, font);
    184 				if (!added) {
    185 					cho_font_free(font);
    186 				}
    187 			}
    188 			for (li = (*se)->lines; *li; li++) {
    189 				for (above = (*li)->text_above; *above; above++) {
    190 					if ((*above)->is_chord) {
    191 						style = (*above)->u.chord->style;
    192 					} else {
    193 						style = (*above)->u.annot->style;
    194 					}
    195 					if (style->font->family) {
    196 						font = cho_font_copy(style->font);
    197 						added = fonts_add_if_not_in(&fonts, font);
    198 						if (!added) {
    199 							cho_font_free(font);
    200 						}
    201 					}
    202 				}
    203 				for (it = (*li)->items; *it; it++) {
    204 					if ((*it)->is_text) {
    205 						style = (*it)->u.text->style;
    206 						if (style->font->family) {
    207 							font = cho_font_copy(style->font);
    208 							added = fonts_add_if_not_in(&fonts, font);
    209 							if (!added) {
    210 								cho_font_free(font);
    211 							}
    212 						}
    213 					}
    214 				}
    215 			}
    216 		}
    217 	}
    218 	return fonts;
    219 }
    220 
    221 static int
    222 fontpath_count_fonts(FcChar8 *path)
    223 {
    224 	int count;
    225 	FcFontSet *set;
    226 
    227 	set = FcFontSetCreate();
    228 	if (!FcFileScan(set, NULL, NULL, NULL, path, false)) {
    229 		DEBUG("fontpath_count_fonts failed.");
    230 		FcFontSetDestroy(set);
    231 		return -1;
    232 	}
    233 	count = set->nfont;
    234 	FcFontSetDestroy(set);
    235 	return count;
    236 }
    237 
    238 static FcPattern *
    239 fontconfig_pattern_create(struct Font *font, enum FontType font_type)
    240 {
    241 	FcPattern *pattern;
    242 	FcValue family, wrapper, variable, width, type, style, weight;
    243 
    244 	pattern = FcPatternCreate();
    245 	if (!pattern) {
    246 		DEBUG("FcPatternCreate failed.\n");
    247 		return NULL;
    248 	}
    249 	family.type = FcTypeString;
    250 	family.u.s = (FcChar8 *)font->family;
    251 	wrapper.type = FcTypeString;
    252 	wrapper.u.s = (FcChar8 *)"SFNT";
    253 	variable.type = FcTypeBool;
    254 	variable.u.b = FcFalse;
    255 	width.type = FcTypeInteger;
    256 	width.u.i = FC_WIDTH_NORMAL;
    257 	type.type = FcTypeString;
    258 	type.u.s = (FcChar8 *)(font_type == FONT_TYPE_OTF ? "CFF" : "TrueType");
    259 	style.type = FcTypeInteger;
    260 	switch (font->style) {
    261 	case FONT_STYLE_ROMAN:
    262 		style.u.i = FC_SLANT_ROMAN;
    263 		break;
    264 	case FONT_STYLE_OBLIQUE:
    265 		style.u.i = FC_SLANT_OBLIQUE;
    266 		break;
    267 	case FONT_STYLE_ITALIC:
    268 		style.u.i = FC_SLANT_ITALIC;
    269 		break;
    270 	}
    271 	weight.type = FcTypeInteger;
    272 	weight.u.i = font->weight == FONT_WEIGHT_REGULAR ? FC_WEIGHT_REGULAR : FC_WEIGHT_BOLD;
    273 	FcPatternAdd(pattern, FC_FAMILY, family, FcFalse);
    274 	FcPatternAdd(pattern, FC_FONT_WRAPPER, wrapper, FcFalse);
    275 	FcPatternAdd(pattern, FC_VARIABLE, variable, FcFalse);
    276 	FcPatternAdd(pattern, FC_WIDTH, width, FcFalse);
    277 	FcPatternAdd(pattern, FC_FONTFORMAT, type, FcFalse);
    278 	FcPatternAdd(pattern, FC_SLANT, style, FcFalse);
    279 	FcPatternAdd(pattern, FC_WEIGHT, weight, FcFalse);
    280 	return pattern;
    281 }
    282 
    283 static char *
    284 fontpath_find(struct Font *font, enum FontType font_type)
    285 {
    286 	FcChar8 *file;
    287 	FcFontSet *set;
    288 	FcObjectSet *obj;
    289 	FcPattern *pattern, *match;
    290 	FcResult result;
    291 	int i;
    292 	char *filepath = NULL;
    293 
    294 	pattern = fontconfig_pattern_create(font, font_type);
    295 	if (!pattern) {
    296 		DEBUG("fontconfig_pattern_create failed.\n");
    297 		return NULL;
    298 	}
    299 	if (
    300 		!strcmp(font->family, "sans") ||
    301 		!strcmp(font->family, "serif") ||
    302 		!strcmp(font->family, "monospace")
    303 	) {
    304 		// pattern = FcNameParse((const FcChar8 *)font->family);
    305 		FcConfigSubstitute(0, pattern, FcMatchPattern);
    306 		FcDefaultSubstitute(pattern);
    307 		match = FcFontMatch(NULL, pattern, &result);
    308 		if (FcPatternGetString(match, FC_FILE, 0, &file) == FcResultMatch) {
    309 			if (
    310 				!file_extension_equals((const char *)file, "ttc") &&
    311 				fontpath_count_fonts(file) == 1
    312 			) {
    313 				filepath = strdup((const char *)file);
    314 			}
    315 		}
    316 		FcPatternDestroy(match);
    317 	} else {
    318 		obj = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WIDTH, FC_WEIGHT, FC_FONTFORMAT, FC_FONT_WRAPPER, FC_FILE, NULL);
    319 		set = FcFontList(NULL, pattern, obj);
    320 		for (i = 0; i<set->nfont; i++) {
    321 			if (FcPatternGetString(set->fonts[i], FC_FILE, 0, &file) == FcResultMatch) {
    322 				if (
    323 					!file_extension_equals((const char *)file, "ttc") &&
    324 					fontpath_count_fonts(file) == 1
    325 				) {
    326 					filepath = strdup((const char *)file);
    327 					break;
    328 				}
    329 			}
    330 		}
    331 		FcObjectSetDestroy(obj);
    332 		FcFontSetDestroy(set);
    333 	}
    334 	FcPatternDestroy(pattern);
    335 	return filepath;
    336 }
    337 
    338 static bool
    339 pdf_load_chord_diagram_fonts(struct PDFContext *ctx)
    340 {
    341 	char *fontpath;
    342 	const char *font_name;
    343 	struct Obj *fnt;
    344 	struct Font font = {
    345 		.family = DEFAULT_FONT,
    346 		.style = FONT_STYLE_ROMAN,
    347 		.weight = FONT_WEIGHT_REGULAR
    348 	};
    349 
    350 	fnt = obj_new();
    351 	fnt->name = strdup("chord-diagram-regular-font");
    352 	if ((font_name = is_base_font(&font))) {
    353 		fnt->value = pdfioFileCreateFontObjFromBase(ctx->pdf_file, font_name);
    354 		ctx->diagram_font_is_base_font = true;
    355 	} else {
    356 		fontpath = fontpath_find(&font, FONT_TYPE_TTF);
    357 		if (!fontpath) {
    358 			fontpath = fontpath_find(&font, FONT_TYPE_OTF);
    359 			if (!fontpath) {
    360 				DEBUG("fontpath_find failed.");
    361 				obj_free(fnt);
    362 				return false;
    363 			}
    364 		}
    365 		fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
    366 		free(fontpath);
    367 	}
    368 	objs_add_obj(&ctx->fonts, fnt);
    369 	fnt = obj_new();
    370 	fnt->name = strdup("chord-diagram-symbols");
    371 	fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, SYMBOLS_FILEPATH, true);
    372 	objs_add_obj(&ctx->fonts, fnt);
    373 	return true;
    374 }
    375 
    376 static bool
    377 font_name_is_path(const char *name)
    378 {
    379 	if (strchr(name, '/')) {
    380 		return true;
    381 	}
    382 	if (file_extension_equals(name, "ttf") || file_extension_equals(name, "otf")) {
    383 		return true;
    384 	}
    385 	return false;
    386 }
    387 
    388 static bool
    389 pdf_load_fonts(struct PDFContext *ctx, struct Font **needed_fonts)
    390 {
    391 	char *fontpath = NULL;
    392 	char **fontpaths = NULL;
    393 	const char *name;
    394 	int index;
    395 	struct Font **f;
    396 	struct Obj *fnt = NULL;
    397 
    398 	for (f = needed_fonts; *f; f++) {
    399 		if (font_name_is_path((*f)->family)) {
    400 			fontpath = filepath_resolve_tilde((*f)->family);
    401 			fnt = obj_new();
    402 			fnt->name = fnt_name_create(*f);
    403 			index = strs_get_index_if_in(fontpaths, fontpath);
    404 			if (index == -1) {
    405 				fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
    406 				if (!fnt->value) {
    407 					DEBUG("pdfioFileCreateFontObjFromFile failed.");
    408 					goto ERR;
    409 				}
    410 				strs_add(&fontpaths, fontpath);
    411 				util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", (*f)->family);
    412 			} else {
    413 				fnt->value = ctx->fonts[index]->value;
    414 			}
    415 			free(fontpath);
    416 			// cho_font_print(*f);
    417 			objs_add_obj(&ctx->fonts, fnt);
    418 		} else
    419 		if ((name = is_base_font(*f))) {
    420 			fnt = obj_new();
    421 			fnt->name = fnt_name_create(*f);
    422 			fnt->value = pdfioFileCreateFontObjFromBase(ctx->pdf_file, name);
    423 			if (!fnt->value) {
    424 				DEBUG("pdfioFileCreateFontObjFromBase failed.");
    425 				goto ERR;
    426 			}
    427 			objs_add_obj(&ctx->fonts, fnt);
    428 		} else {
    429 			fontpath = fontpath_find(*f, FONT_TYPE_TTF);
    430 			if (fontpath) {
    431 				fnt = obj_new();
    432 				fnt->name = fnt_name_create(*f);
    433 				index = strs_get_index_if_in(fontpaths, fontpath);
    434 				if (index == -1) {
    435 					fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
    436 					if (!fnt->value) {
    437 						DEBUG("pdfioFileCreateFontObjFromFile failed.");
    438 						goto ERR;
    439 					}
    440 					strs_add(&fontpaths, fontpath);
    441 					util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath);
    442 				} else {
    443 					fnt->value = ctx->fonts[index]->value;
    444 				}
    445 				// cho_font_print(*f);
    446 				objs_add_obj(&ctx->fonts, fnt);
    447 				free(fontpath);
    448 			} else {
    449 				fontpath = fontpath_find(*f, FONT_TYPE_OTF);
    450 				if (fontpath) {
    451 					fnt = obj_new();
    452 					fnt->name = fnt_name_create(*f);
    453 					index = strs_get_index_if_in(fontpaths, fontpath);
    454 					if (index == -1) {
    455 						fnt->value = pdfioFileCreateFontObjFromFile(ctx->pdf_file, fontpath, true);
    456 						if (!fnt->value) {
    457 							DEBUG("pdfioFileCreateFontObjFromFile failed.");
    458 							goto ERR;
    459 						}
    460 						strs_add(&fontpaths, fontpath);
    461 						util_log(NULL, 0, LOG_INFO, "Loaded font from '%s'.", fontpath);
    462 					} else {
    463 						fnt->value = ctx->fonts[index]->value;
    464 					}
    465 					// cho_font_print(*f);
    466 					objs_add_obj(&ctx->fonts, fnt);
    467 					free(fontpath);
    468 				} else {
    469 					util_log(NULL, 0, LOG_ERR, "Didn't find font file for following font:");
    470 					cho_font_print(*f);
    471 					goto ERR;
    472 				}
    473 			}
    474 		}
    475 	}
    476 	if (ctx->config->output->diagram->show) {
    477 		if (!pdf_load_chord_diagram_fonts(ctx)) {
    478 			DEBUG("pdf_load_chord_diagram_fonts failed.");
    479 			goto ERR;
    480 		}
    481 	}
    482 	strs_free(fontpaths);
    483 	return true;
    484 	ERR:
    485 	strs_free(fontpaths);
    486 	objs_free(ctx->fonts);
    487 	obj_free(fnt);
    488 	free(fontpath);
    489 	return false;
    490 }
    491 
    492 static char *
    493 pdf_filename_generate_from_songs(struct PDFContext *ctx, struct ChoSong **songs)
    494 {
    495 	char *filename, *normalized_title, *title;
    496 	struct ChoStyle *unused;
    497 	int len;
    498 
    499 	len = cho_song_count(songs);
    500 	if (len == 0) {
    501 		return NULL;
    502 	}
    503 	if (len == 1) {
    504 		if (!cho_metadata_value(songs[0]->metadata, "title", ctx->config->metadata_separator, &title, &unused)) {
    505 			DEBUG("cho_metadata_value failed.");
    506 			return NULL;
    507 		}
    508 		normalized_title = str_normalize(title);
    509 		filename = file_extension_replace_or_add(normalized_title, "pdf");
    510 		free(normalized_title);
    511 		free(title);
    512 		return filename;
    513 	}
    514 	return strdup("collection-of-songs.pdf");
    515 }
    516 
    517 static char *
    518 pdf_filepath_create(
    519 	struct PDFContext *ctx,
    520 	struct ChoSong **songs,
    521 	const char *cho_filepath,
    522 	const char *out
    523 )
    524 {
    525 	char *pdf_filepath = NULL;
    526 	char *filepath = NULL;
    527 	char *filename = NULL;
    528 	char *tmp = NULL;
    529 	enum FileType type;
    530 
    531 	if (cho_filepath) {
    532 		filepath = file_extension_replace_or_add(cho_filepath, "pdf");
    533 		filename = filepath_basename(filepath);
    534 	} else {
    535 		filename = pdf_filename_generate_from_songs(ctx, songs);
    536 		if (!filename) {
    537 			DEBUG("pdf_filename_generate_from_songs failed.");
    538 			return NULL;
    539 		}
    540 	}
    541 	if (out) {
    542 		type = file_type(out);
    543 		switch (type) {
    544 		case FILE_TYPE_ERROR: {
    545 			tmp = filepath_dirname(out);
    546 			type = file_type(tmp);
    547 			switch (type) {
    548 			case FILE_TYPE_FOLDER:
    549 				pdf_filepath = strdup(out);
    550 				break;
    551 			default:
    552 				util_log(NULL, 0, LOG_ERR, "The -o/--output value '%s' is not an existing folder.", out);
    553 			}
    554 			break;
    555 		}
    556 		case FILE_TYPE_REG_FILE: {
    557 			pdf_filepath = strdup(out);
    558 			break;
    559 		}
    560 		case FILE_TYPE_FOLDER: {
    561 			pdf_filepath = filepath_add_ending_slash_if_missing(out);
    562 			pdf_filepath = erealloc(pdf_filepath, (strlen(pdf_filepath)+strlen(filename)+1) * sizeof(char));
    563 			strcat(pdf_filepath, filename);
    564 			break;
    565 		}
    566 		case FILE_TYPE_OTHER: {
    567 			util_log(NULL, 0, LOG_ERR, "Invalid argument --output/-o value. It doesn't refer to a folder or regular file.");
    568 			break;
    569 		}
    570 		}
    571 	} else {
    572 		if (filepath) {
    573 			pdf_filepath = strdup(filepath);
    574 		} else {
    575 			pdf_filepath = strdup(filename);
    576 		}
    577 	}
    578 	free(filepath);
    579 	free(filename);
    580 	free(tmp);
    581 	return pdf_filepath;
    582 }
    583 
    584 static bool
    585 pdf_font_set(struct PDFContext *ctx, pdfio_stream_t *stream, struct Font *font)
    586 {
    587 	static int page_index = 0;
    588 	char *name = fnt_name_create(font);
    589 	if (
    590 		!strcmp(name, ctx->current_font_name) &&
    591 		font->size == ctx->current_font_size &&
    592 		ctx->current_page_index == page_index
    593 	) {
    594 		free(name);
    595 		return true;
    596 	}
    597 	if (!pdfioContentSetTextFont(stream, name, font->size)) {
    598 		DEBUG("pdfioContentSetTextFont failed.");
    599 		free(name);
    600 		return false;
    601 	}
    602 	strcpy(ctx->current_font_name, name);
    603 	ctx->current_font_size = font->size;
    604 	page_index = ctx->current_page_index;
    605 	free(name);
    606 	return true;
    607 }
    608 
    609 static double
    610 text_width(struct PDFContext *ctx, const char *text, struct ChoStyle *style)
    611 {
    612 	char *name = fnt_name_create(style->font);
    613 	pdfio_obj_t *font_obj = out_pdf_fnt_obj_get_by_name(ctx, name);
    614 	if (!font_obj) {
    615 		DEBUG("out_pdf_fnt_obj_get_by_name failed.");
    616 		free(name);
    617 		return -1.0;
    618 	}
    619 	free(name);
    620 	return pdfioContentTextMeasure(font_obj, text, style->font->size);
    621 }
    622 
    623 static double
    624 text_above_width(struct PDFContext *ctx, struct ChoLineItemAbove *above)
    625 {
    626 	double width;
    627 	if (above->is_chord) {
    628 		char *name;
    629 		name = cho_chord_name_generate(above->u.chord);
    630 		width = text_width(ctx, name, above->u.chord->style);
    631 		if (width == ERROR) {
    632 			DEBUG("text_width failed.");
    633 			free(name);
    634 			return ERROR;
    635 		}
    636 		free(name);
    637 	} else {
    638 		width = text_width(ctx, above->u.annot->text, above->u.annot->style);
    639 		if (width == ERROR) {
    640 			DEBUG("text_width failed.");
    641 			return ERROR;
    642 		}
    643 	}
    644 	return width;
    645 }
    646 
    647 static int
    648 find_whitespace(const char *str, size_t start)
    649 {
    650 	int i;
    651 	for (i = start; i>=0; i--) {
    652 		if (str[i] == ' ' || str[i] == '\t') {
    653 			return i;
    654 		}
    655 	}
    656 	return -1;
    657 }
    658 
    659 static int
    660 text_find_fitting(
    661 	struct PDFContext *ctx,
    662 	const char *str,
    663 	struct ChoStyle *style,
    664 	double x,
    665 	double max_width
    666 )
    667 {
    668 	size_t len = strlen(str);
    669 	size_t start = len - 1;
    670 	char tmp[len+1];
    671 	strcpy((char *)&tmp, str);
    672 	double width;
    673 	int i;
    674 
    675 	do {
    676 		i = find_whitespace((const char *)&tmp, start);
    677 		if (i == -1) {
    678 			util_log(NULL, 0, LOG_ERR, "Can't split text because no whitespace was found.");
    679 			return -1;
    680 		}
    681 		tmp[i] = 0;
    682 		width = text_width(ctx, (const char *)&tmp, style);
    683 		if (width == ERROR) {
    684 			DEBUG("text_width failed.");
    685 			return -1;
    686 		}
    687 		start = i - 1;
    688 	} while (x + width > max_width);
    689 	return i;
    690 }
    691 
    692 static bool
    693 pdf_draw_line(
    694 	pdfio_stream_t *stream,
    695 	struct PDFText *text,
    696 	double y,
    697 	double width,
    698 	enum LineLocation line_location
    699 )
    700 {
    701 	double red, green, blue;
    702 
    703 	switch (line_location) {
    704 	case LINE_LOCATION_UNDER:
    705 		red = text->style->underline_color->red / 255.0;
    706 		green = text->style->underline_color->green / 255.0;
    707 		blue = text->style->underline_color->blue / 255.0;
    708 		y -= 2.0;
    709 		break;
    710 	case LINE_LOCATION_STRIKETHROUGH:
    711 		red = text->style->strikethrough_color->red / 255.0;
    712 		green = text->style->strikethrough_color->green / 255.0;
    713 		blue = text->style->strikethrough_color->blue / 255.0;
    714 		y += text->style->font->size * 0.3;
    715 		break;
    716 	case LINE_LOCATION_OVER:
    717 		red = text->style->overline_color->red / 255.0;
    718 		green = text->style->overline_color->green / 255.0;
    719 		blue = text->style->overline_color->blue / 255.0;
    720 		y += text->style->font->size * 0.8;
    721 		break;
    722 	}
    723 	if (!pdfioContentPathMoveTo(stream, text->x, y)) {
    724 		DEBUG("pdfioContentPathMoveTo failed.");
    725 		return false;
    726 	}
    727 	if (!pdfioContentPathLineTo(stream, text->x + width, y)) {
    728 		DEBUG("pdfioContentPathLineTo failed.");
    729 		return false;
    730 	}
    731 	if (!pdfioContentSetStrokeColorRGB(stream, red, green, blue)) {
    732 		DEBUG("pdfioContentSetStrokeColorRGB failed.");
    733 		return false;
    734 	}
    735 	if (!pdfioContentStroke(stream)) {
    736 		DEBUG("pdfioContentStroke failed.");
    737 		return false;
    738 	}
    739 	return true;
    740 }
    741 
    742 static bool
    743 pdf_draw_rectangle(
    744 	pdfio_stream_t *stream,
    745 	struct PDFText *text
    746 )
    747 {
    748 	double height;
    749 	double red, green, blue;
    750 
    751 	red = text->style->background_color->red / 255.0;
    752 	green = text->style->background_color->green / 255.0;
    753 	blue = text->style->background_color->blue / 255.0;
    754 	if (!pdfioContentSetFillColorRGB(stream, red, green, blue)) {
    755 		fprintf(stderr, "pdfioContentSetFillColorRGB failed.\n");
    756 		return false;
    757 	}
    758 	height = (8.0 + text->style->font->size) - text->style->font->size * 0.8;
    759 	if (!pdfioContentPathRect(stream, text->x, text->y, text->width, height)) {
    760 		fprintf(stderr, "pdfioContentPathRect failed.\n");
    761 		return false;
    762 	}
    763 	if (!pdfioContentFill(stream, true)) {
    764 		fprintf(stderr, "pdfioContentFill failed.\n");
    765 		return false;
    766 	}
    767 	return true;
    768 }
    769 
    770 static bool
    771 is_purest_white(struct RGBColor *color)
    772 {
    773 	if (color->red == 255 && color->green == 255 && color->blue == 255) {
    774 		return true;
    775 	}
    776 	return false;
    777 }
    778 
    779 static bool
    780 pdf_text_show(struct PDFContext *ctx, pdfio_stream_t *stream, struct PDFText *text)
    781 {
    782 	double red, green, blue;
    783 	bool unicode;
    784 
    785 	if (!pdf_font_set(ctx, stream, text->style->font)) {
    786 		DEBUG("pdf_font_set failed.");
    787 		return false;
    788 	}
    789 	unicode = !is_base_font(text->style->font);
    790 	if (!is_purest_white(text->style->background_color)) {
    791 		if (!pdf_draw_rectangle(stream, text)) {
    792 			DEBUG("draw_rectangle failed.");
    793 			return false;
    794 		}
    795 	}
    796 	red = text->style->foreground_color->red / 255.0;
    797 	green = text->style->foreground_color->green / 255.0;
    798 	blue = text->style->foreground_color->blue / 255.0;
    799 	if (!pdfioContentSetFillColorRGB(stream, red, green, blue)) {
    800 		DEBUG("pdfioContentSetFillColorRGB failed.");
    801 		return false;
    802 	}
    803 	if (!pdfioContentTextBegin(stream)) {
    804 		DEBUG("pdfioContentTextBegin failed.");
    805 		return false;
    806 	}
    807 	if (!pdfioContentTextMoveTo(stream, text->x, text->y)) {
    808 		DEBUG("pdfioContentTextMoveTo failed.");
    809 		return false;
    810 	}
    811 	if (!pdfioContentSetTextRise(stream, text->style->rise)) {
    812 		DEBUG("pdfioContentSetTextRise failed.");
    813 		return false;
    814 	}
    815 	if (!pdfioContentTextShow(stream, unicode, text->text)) {
    816 		DEBUG("pdfioContentTextShow failed.");
    817 		return false;
    818 	}
    819 	if (!pdfioContentTextEnd(stream)) {
    820 		DEBUG("pdfioContentTextEnd failed.");
    821 		return false;
    822 	}
    823 	if (text->style->underline_style == LINE_STYLE_SINGLE) {
    824 		pdf_draw_line(stream, text, text->y, text->width, LINE_LOCATION_UNDER);
    825 	} else if (text->style->underline_style == LINE_STYLE_DOUBLE) {
    826 		pdf_draw_line(stream, text, text->y, text->width, LINE_LOCATION_UNDER);
    827 		pdf_draw_line(stream, text, text->y-1.5, text->width, LINE_LOCATION_UNDER);
    828 	}
    829 	if (text->style->strikethrough) {
    830 		pdf_draw_line(stream, text, text->y, text->width, LINE_LOCATION_STRIKETHROUGH);
    831 	}
    832 	if (text->style->overline_style == LINE_STYLE_SINGLE) {
    833 		pdf_draw_line(stream, text, text->y, text->width, LINE_LOCATION_OVER);
    834 	} else if (text->style->overline_style == LINE_STYLE_DOUBLE) {
    835 		pdf_draw_line(stream, text, text->y, text->width, LINE_LOCATION_OVER);
    836 		pdf_draw_line(stream, text, text->y+1.5, text->width, LINE_LOCATION_OVER);
    837 	}
    838 	if (text->style->boxed) {
    839 		red = text->style->boxed_color->red / 255.0;
    840 		green = text->style->boxed_color->green / 255.0;
    841 		blue = text->style->boxed_color->blue / 255.0;
    842 		if (!pdfioContentSetStrokeColorRGB(stream, red, green, blue)) {
    843 			DEBUG("pdfioContentSetFillColorRGB failed.");
    844 			return false;
    845 		}
    846 		if (!pdfioContentPathRect(
    847 			stream,
    848 			text->x - 2.0,
    849 			text->y - 2.0,
    850 			text->width + 4.0,
    851 			text->style->font->size * 0.8 + 4.0
    852 		)) {
    853 			DEBUG("pdfioContentPathRect failed.");
    854 			return false;
    855 		}
    856 		if (!pdfioContentStroke(stream)) {
    857 			DEBUG("pdfioContentStroke failed.");
    858 			return false;
    859 		}
    860 	}
    861 	return true;
    862 }
    863 
    864 static bool
    865 annot_page_link_add(
    866 	struct PDFContext *ctx,
    867 	struct TocEntry *entry,
    868 	int toc_page_count,
    869 	int line_count,
    870 	double font_size
    871 )
    872 {
    873 	int page_index;
    874 	pdfio_rect_t rect;
    875 	pdfio_dict_t *annot;
    876 	pdfio_array_t *destination;
    877 
    878 	rect.x1 = MARGIN_HORIZONTAL;
    879 	rect.x2 = MARGIN_HORIZONTAL + LINE_WIDTH;
    880 	rect.y1 = ctx->t_ctx.y - 2.0;
    881 	rect.y2 = ctx->t_ctx.y + (8.0 + font_size) * line_count - font_size * 0.8;
    882 	page_index = entry->page_index + toc_page_count;
    883 	annot = pdfioDictCreate(ctx->pdf_file);
    884 	if (!pdfioDictSetName(annot, "Subtype", "Link")) {
    885 		DEBUG("pdfioDictSetName failed.");
    886 		return false;
    887 	}
    888 	if (!pdfioDictSetRect(annot, "Rect", &rect)) {
    889 		DEBUG("pdfioDictSetRect failed.");
    890 		return false;
    891 	}
    892 	destination = pdfioArrayCreate(ctx->pdf_file);
    893 	if (!pdfioArrayAppendNumber(destination, page_index)) {
    894 		DEBUG("pdfioArrayAppendNumber failed.");
    895 		return false;
    896 	}
    897 	if (!pdfioArrayAppendName(destination, "FitH")) {
    898 		DEBUG("pdfioArrayAppendName failed.");
    899 		return false;
    900 	}
    901 	// TODO: Is this constant '30.0' correct with different font sizes, etc. ?
    902 	// clicking the annotation should show the song including the song title at the top
    903 	if (!pdfioArrayAppendNumber(destination, entry->page_y + 30.0)) {
    904 		DEBUG("pdfioArrayAppendNumber failed.");
    905 		return false;
    906 	}
    907 	if (!pdfioDictSetArray(annot, "Dest", destination)) {
    908 		DEBUG("pdfioDictSetArray failed.");
    909 		return false;
    910 	}
    911 	if (!pdfioArrayAppendDict(ctx->t_ctx.content->pages[ctx->t_ctx.page]->annots, annot)) {
    912 		DEBUG("pdfioArrayAppendDict failed.");
    913 		return false;
    914 	}
    915 	return true;
    916 }
    917 
    918 static bool
    919 annot_url_link_add(
    920 	struct PDFContext *ctx,
    921 	struct PDFContentContext *c_ctx,
    922 	struct ChoStyle *style,
    923 	double width
    924 )
    925 {
    926 	pdfio_rect_t rect;
    927 	pdfio_dict_t *annot, *action;
    928 
    929 	rect.x1 = c_ctx->x;
    930 	rect.x2 = c_ctx->x + width;
    931 	rect.y1 = c_ctx->y - 2.0;
    932 	rect.y2 = c_ctx->y + style->font->size * 0.8;
    933 	annot = pdfioDictCreate(ctx->pdf_file);
    934 	if (!pdfioDictSetName(annot, "Subtype", "Link")) {
    935 		DEBUG("pdfioDictSetName failed.");
    936 		return false;
    937 	}
    938 	if (!pdfioDictSetRect(annot, "Rect", &rect)) {
    939 		DEBUG("pdfioDictSetRect failed.");
    940 		return false;
    941 	}
    942 	action = pdfioDictCreate(ctx->pdf_file);
    943 	if (!pdfioDictSetName(action, "S", "URI")) {
    944 		DEBUG("pdfioDictSetName failed.");
    945 		return false;
    946 	}
    947 	if (!pdfioDictSetString(action, "URI", style->href)) {
    948 		DEBUG("pdfioDictSetString failed.");
    949 		return false;
    950 	}
    951 	if (!pdfioDictSetDict(annot, "A", action)) {
    952 		DEBUG("pdfioDictSetDict failed.");
    953 		return false;
    954 	}
    955 	if (!pdfioArrayAppendDict(c_ctx->content->pages[c_ctx->page]->annots, annot)) {
    956 		DEBUG("pdfioArrayAppendDict failed.");
    957 		return false;
    958 	}
    959 	return true;
    960 }
    961 
    962 static bool
    963 pdf_set_title(struct PDFContext *ctx, struct ChoSong **songs)
    964 {
    965 	// INFO: Set pdf title only if a single song exist
    966 	if (songs[0] && !songs[1]) {
    967 		char *title;
    968 		struct ChoStyle *unused;
    969 		if (!cho_metadata_value(songs[0]->metadata, "title", ctx->config->metadata_separator, &title, &unused)) {
    970 			DEBUG("cho_metadata_value failed.");
    971 			return false;
    972 		}
    973 		pdfioFileSetTitle(ctx->pdf_file, title);
    974 		free(title);
    975 	}
    976 	return true;
    977 }
    978 
    979 static pdfio_stream_t *
    980 pdf_page_create(
    981 	struct PDFContext *ctx,
    982 	struct PDFImage **imgs,
    983 	pdfio_array_t *annots
    984 )
    985 {
    986 	pdfio_dict_t *page_dict;
    987 	pdfio_stream_t *page_stream;
    988 	pdfio_array_t *color_array;
    989 	struct Obj **f;
    990 	struct PDFImage **i;
    991 	
    992 	color_array = pdfioArrayCreateColorFromStandard(ctx->pdf_file, 3, PDFIO_CS_ADOBE);
    993 	page_dict = pdfioDictCreate(ctx->pdf_file);
    994 	if (!pdfioPageDictAddColorSpace(page_dict, "rgbcolorspace", color_array)) {
    995 		DEBUG("pdfioPageDictAddColorSpace failed.");
    996 		return NULL;
    997 	}
    998 	if (!pdfioDictSetArray(page_dict, "Annots", annots)) {
    999 		DEBUG("pdfioDictSetArray failed.");
   1000 		return NULL;
   1001 	}
   1002 	if (imgs) {
   1003 		for (i = imgs; *i; i++) {
   1004 			if (!pdfioPageDictAddImage(page_dict, (*i)->name, (*i)->obj)) {
   1005 				DEBUG("pdfioPageDictAddImage failed.");
   1006 				return NULL;
   1007 			}
   1008 		}
   1009 	}
   1010 	for (f = ctx->fonts; *f; f++) {
   1011 		if (!pdfioPageDictAddFont(page_dict, (*f)->name, (*f)->value)) {
   1012 			DEBUG("pdfioPageDictAddFont failed.");
   1013 			return NULL;
   1014 		}
   1015 	}
   1016 	page_stream = pdfioFileCreatePage(ctx->pdf_file, page_dict);
   1017 	if (!pdfioContentSetFillColorSpace(page_stream, "rgbcolorspace")) {
   1018 		DEBUG("pdfioContentSetFillColorSpace failed.");
   1019 		return NULL;
   1020 	}
   1021 	if (!pdfioContentSetStrokeColorSpace(page_stream, "rgbcolorspace")) {
   1022 		DEBUG("pdfioContentSetStrokeColorSpace failed.");
   1023 		return NULL;
   1024 	}
   1025 	return page_stream;
   1026 }
   1027 
   1028 static double
   1029 image_width(struct ChoImage *image, pdfio_obj_t *obj)
   1030 {
   1031 	double width;
   1032 	width = pdfioImageGetWidth(obj);
   1033 	if (image->width) {
   1034 		if (image->width->type == SIZE_TYPE_POINT) {
   1035 			width = image->width->d;
   1036 		} else
   1037 		if (image->width->type == SIZE_TYPE_PERCENT) {
   1038 			width = LINE_WIDTH * image->width->d;
   1039 		}
   1040 	}
   1041 	if (image->width_scale) {
   1042 		width *= image->width_scale->d;
   1043 	}
   1044 	width += image->border;
   1045 	return width;
   1046 }
   1047 
   1048 static double
   1049 image_height(struct ChoImage *image, pdfio_obj_t *obj)
   1050 {
   1051 	double height;
   1052 	height = pdfioImageGetHeight(obj);
   1053 	if (image->height) {
   1054 		if (image->height->type == SIZE_TYPE_POINT) {
   1055 			height = image->height->d;
   1056 		} else
   1057 		if (image->height->type == SIZE_TYPE_PERCENT) {
   1058 			height = LINE_WIDTH * image->height->d;
   1059 		}
   1060 	}
   1061 	if (image->height_scale) {
   1062 		height *= image->height_scale->d;
   1063 	}
   1064 	height += image->border;
   1065 	return height;
   1066 }
   1067 
   1068 static char *
   1069 image_name(struct PDFContext *ctx, struct ChoImage *image)
   1070 {
   1071 	char tmp[PATH_MAX];
   1072 	char *image_path;
   1073 	struct stat s;
   1074 
   1075 	if (strchr(image->src, '/')) {
   1076 		image_path = image->src;
   1077 	} else {
   1078 		strcpy((char *)&tmp, ctx->cho_dirpath);
   1079 		strcat((char *)&tmp, "/");
   1080 		strcat((char *)&tmp, image->src);
   1081 		image_path = (char *)&tmp;
   1082 	}
   1083 	if (stat(image_path, &s)) {
   1084 		DEBUG("stat failed.");
   1085 		util_log(NULL, 0, LOG_ERR, "%s: %s", image_path, strerror(errno));
   1086 		return NULL;
   1087 	}
   1088 	memset(tmp, 0, PATH_MAX);
   1089 	snprintf((char *)&tmp, PATH_MAX, "%ld", s.st_ino);
   1090 	return strdup(tmp);
   1091 }
   1092 
   1093 static bool
   1094 pdf_load_images(struct PDFContext *ctx, struct Obj ***images, struct ChoSong **songs)
   1095 {
   1096 	struct ChoSong **s;
   1097 	struct ChoSection **se;
   1098 	struct ChoLine **li;
   1099 	struct ChoLineItem **it;
   1100 	int i = 0;
   1101 	char filepath[PATH_MAX];
   1102 	char *name;
   1103 	char *image_filepath;
   1104 
   1105 	for (s = songs; *s; s++) {
   1106 		for (se = (*s)->sections; *se; se++) {
   1107 			for (li = (*se)->lines; *li; li++) {
   1108 				for (it = (*li)->items; *it; it++) {
   1109 					if (!(*it)->is_text) {
   1110 						memset(filepath, 0, PATH_MAX);
   1111 						strcpy((char *)&filepath, ctx->cho_dirpath);
   1112 						strcat((char *)&filepath, "/");
   1113 						strcat((char *)&filepath, (*it)->u.image->src);
   1114 						name = image_name(ctx, (*it)->u.image);
   1115 						if (!name) {
   1116 							DEBUG("image_name failed.");
   1117 							return false;
   1118 						}
   1119 						if (!objs_get_obj(*images, name)) {
   1120 							*images = erealloc(*images, (i+2) * sizeof(struct Obj *));
   1121 							(*images)[i] = obj_new();
   1122 							(*images)[i]->name = strdup(name);
   1123 							if (strchr((*it)->u.image->src, '/')) {
   1124 								image_filepath = (*it)->u.image->src;
   1125 							} else {
   1126 								image_filepath = (char *)&filepath;
   1127 							}
   1128 							(*images)[i]->value = pdfioFileCreateImageObjFromFile(ctx->pdf_file, image_filepath, true);
   1129 							if (!(*images)[i]->value) {
   1130 								DEBUG("pdfioFileCreateImageObjFromFile failed.");
   1131 								free(name);
   1132 								return false;
   1133 							}
   1134 							util_log(NULL, 0, LOG_INFO, "Loaded image from '%s'.", image_filepath);
   1135 							(*images)[i+1] = NULL;
   1136 						}
   1137 						free(name);
   1138 						i++;
   1139 					}
   1140 				}
   1141 			}
   1142 		}
   1143 	}
   1144 	return true;
   1145 }
   1146 
   1147 static struct ChoChord **
   1148 pdf_get_chords(struct ChoSong *song)
   1149 {
   1150 	struct ChoSection **se;
   1151 	struct ChoLine **li;
   1152 	struct ChoLineItemAbove **above;
   1153 	struct ChoChord **chords = NULL;
   1154 
   1155 	for (se = song->sections; *se; se++) {
   1156 		for (li = (*se)->lines; *li; li++) {
   1157 			for (above = (*li)->text_above; *above; above++) {
   1158 				if ((*above)->is_chord) {
   1159 					if (!cho_chords_has(chords, (*above)->u.chord)) {
   1160 						cho_chords_add(&chords, (*above)->u.chord);
   1161 					}
   1162 				}
   1163 			}
   1164 		}
   1165 	}
   1166 	return chords;
   1167 }
   1168 
   1169 static double
   1170 line_width_until_text_above(
   1171 	struct PDFContext *ctx,
   1172 	struct ChoLineItem **items,
   1173 	struct ChoLineItemAbove *above,
   1174 	struct Obj **img_objs,
   1175 	struct SpaceNeeded *space
   1176 )
   1177 {
   1178 	int i, save_i, save_k;
   1179 	int k = EMPTY_INT;
   1180 	int pos = 0;
   1181 	double width = 0.0;
   1182 	char *name;
   1183 	pdfio_obj_t *font_obj;
   1184 	pdfio_obj_t *obj;
   1185 	struct ChoText *text;
   1186 
   1187 	for (i = 0; items[i]; i++) {
   1188 		if (items[i]->is_text) {
   1189 			for (k = 0; items[i]->u.text->text[k]; k++) {
   1190 				if (above->position == pos) {
   1191 					save_i = i;
   1192 					save_k = k;
   1193 					goto FOUND;
   1194 				}
   1195 				pos++;
   1196 			}
   1197 		}
   1198 	}
   1199 	/* INFO: If the chord/annotation is the last thing in the line */
   1200 	save_i = i;
   1201 	save_k = k;
   1202 	FOUND:
   1203 	if (space) {
   1204 		space->line_item_index = save_i;
   1205 		space->text_index = save_k;
   1206 	}
   1207 	for (i = 0; items[i] && i <= save_i; i++) {
   1208 		if (items[i]->is_text) {
   1209 			text = items[i]->u.text;
   1210 			name = fnt_name_create(text->style->font);
   1211 			font_obj = out_pdf_fnt_obj_get_by_name(ctx, name);
   1212 			if (!font_obj) {
   1213 				DEBUG("out_pdf_fnt_obj_get_by_name failed.");
   1214 				free(name);
   1215 				return ERROR;
   1216 			}
   1217 			free(name);
   1218 			if (save_i == i) {
   1219 				char tmp[strlen(text->text)+1];
   1220 				strcpy((char *)&tmp, text->text);
   1221 				tmp[save_k] = 0;
   1222 				width += pdfioContentTextMeasure(font_obj, (const char *)&tmp, text->style->font->size);
   1223 			} else {
   1224 				width += pdfioContentTextMeasure(font_obj, text->text, text->style->font->size);
   1225 			}
   1226 		} else {
   1227 			name = image_name(ctx, items[i]->u.image);
   1228 			if (!name) {
   1229 				DEBUG("image_name failed.");
   1230 				return ERROR;
   1231 			}
   1232 			obj = objs_get_obj(img_objs, name);
   1233 			if (!obj) {
   1234 				DEBUG("objs_get_obj failed.");
   1235 				free(name);
   1236 				return ERROR;
   1237 			}
   1238 			width += image_width(items[i]->u.image, obj);
   1239 			free(name);
   1240 		}
   1241 	}
   1242 	return width;
   1243 }
   1244 
   1245 static struct PDFImage *
   1246 pdf_image_new(void)
   1247 {
   1248 	struct PDFImage *image = emalloc(sizeof(struct PDFImage));
   1249 	image->x = 0.0;
   1250 	image->y = 0.0;
   1251 	image->width = 0.0;
   1252 	image->height = 0.0;
   1253 	image->name = NULL;
   1254 	image->obj = NULL;
   1255 	return image;
   1256 }
   1257 
   1258 static void
   1259 pdf_image_free(struct PDFImage *image)
   1260 {
   1261 	if (!image) {
   1262 		return;
   1263 	}
   1264 	free(image->name);
   1265 	free(image);
   1266 }
   1267 
   1268 static struct PDFText *
   1269 pdf_text_new(void)
   1270 {
   1271 	struct PDFText *t = emalloc(sizeof(struct PDFText));
   1272 	t->text = NULL;
   1273 	t->style = NULL;
   1274 	t->x = 0.0;
   1275 	t->y = 0.0;
   1276 	t->width = 0.0;
   1277 	return t;
   1278 }
   1279 
   1280 static void
   1281 pdf_text_free(struct PDFText *text)
   1282 {
   1283 	if (!text) {
   1284 		return;
   1285 	}
   1286 	free(text->text);
   1287 	cho_style_free(text->style);
   1288 	free(text);
   1289 }
   1290 
   1291 static void
   1292 toc_entry_free(struct TocEntry *entry)
   1293 {
   1294 	if (!entry) {
   1295 		return;
   1296 	}
   1297 	free(entry->title);
   1298 	free(entry);
   1299 }
   1300 
   1301 static struct PDFPage *
   1302 pdf_page_new(struct PDFContext *ctx)
   1303 {
   1304 	struct PDFPage *page = emalloc(sizeof(struct PDFPage));
   1305 	page->texts = NULL;
   1306 	page->images = NULL;
   1307 	page->diagrams = NULL;
   1308 	page->annots = pdfioArrayCreate(ctx->pdf_file);
   1309 	return page;
   1310 }
   1311 
   1312 static void
   1313 pdf_page_free(struct PDFPage *page)
   1314 {
   1315 	if (!page) {
   1316 		return;
   1317 	}
   1318 	struct PDFText **t;
   1319 	struct PDFImage **i;
   1320 	struct ChordDiagram **d;
   1321 	if ((t = page->texts)) {
   1322 		for (; *t; t++) {
   1323 			pdf_text_free(*t);
   1324 		}
   1325 		free(page->texts);
   1326 	}
   1327 	if ((i = page->images)) {
   1328 		for (; *i; i++) {
   1329 			pdf_image_free(*i);
   1330 		}
   1331 		free(page->images);
   1332 	}
   1333 	if ((d = page->diagrams)) {
   1334 		for (; *d; d++) {
   1335 			chord_diagram_free(*d);
   1336 		}
   1337 		free(page->diagrams);
   1338 	}
   1339 	free(page);
   1340 }
   1341 
   1342 static void
   1343 pdf_content_context_init(struct PDFContentContext *c_ctx)
   1344 {
   1345 	c_ctx->content = NULL;
   1346 	c_ctx->x = MARGIN_HORIZONTAL;
   1347 	c_ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
   1348 	c_ctx->text = 0;
   1349 	c_ctx->image = 0;
   1350 	c_ctx->diagram = 0;
   1351 	c_ctx->page = 0;
   1352 	c_ctx->toc_entry = 0;
   1353 	c_ctx->spaces = NULL;
   1354 	c_ctx->biggest_font_size = 0.0;
   1355 	c_ctx->consumed_lyrics = 0;
   1356 	c_ctx->prev_added_space = 0.0;
   1357 	c_ctx->margin_bottom = MARGIN_BOTTOM;
   1358 }
   1359 
   1360 static struct PDFContent *
   1361 pdf_content_new(void)
   1362 {
   1363 	struct PDFContent *content = emalloc(sizeof(struct PDFContent));
   1364 	content->pages = NULL;
   1365 	content->toc = NULL;
   1366 	return content;
   1367 }
   1368 
   1369 static void
   1370 pdf_content_free(struct PDFContent *content)
   1371 {
   1372 	if (!content) {
   1373 		return;
   1374 	}
   1375 	struct PDFPage **p;
   1376 	struct TocEntry **toc;
   1377 	for (p = content->pages; *p; p++) {
   1378 		pdf_page_free(*p);
   1379 	}
   1380 	free(content->pages);
   1381 	if ((toc = content->toc)) {
   1382 		for (; *toc; toc++) {
   1383 			toc_entry_free(*toc);
   1384 		}
   1385 		free(content->toc);
   1386 	}
   1387 	free(content);
   1388 }
   1389 
   1390 static void
   1391 spaces_free(struct SpaceNeeded **spaces)
   1392 {
   1393 	if (!spaces) {
   1394 		return;
   1395 	}
   1396 	struct SpaceNeeded **s;
   1397 	for (s = spaces; *s; s++) {
   1398 		free(*s);
   1399 	}
   1400 	free(spaces);
   1401 }
   1402 
   1403 static bool
   1404 calc_space_between_text_above(
   1405 	struct PDFContext *ctx,
   1406 	struct ChoLineItem **items,
   1407 	struct ChoLineItemAbove **text_above,
   1408 	struct Obj **img_objs,
   1409 	struct SpaceNeeded ***spaces
   1410 )
   1411 {
   1412 	if (!*text_above) {
   1413 		return true;
   1414 	}
   1415 	int sp = 0;
   1416 	int i;
   1417 	for (i = 1; text_above[i]; i++) {
   1418 		struct SpaceNeeded space = {
   1419 			.line_item_index = 0,
   1420 			.text_index = 0,
   1421 			.text_above_index = 0,
   1422 			.amount = 0.0
   1423 		};
   1424 		double width_between;
   1425 		double width_until_cur;
   1426 		double width_until_prev;
   1427 		double prev_width;
   1428 		width_until_cur = line_width_until_text_above(ctx, items, text_above[i], img_objs, NULL);
   1429 		if (width_until_cur == ERROR) {
   1430 			DEBUG("line_width_until_text_above failed.");
   1431 			return false;
   1432 		}
   1433 		i--;
   1434 		width_until_prev = line_width_until_text_above(ctx, items, text_above[i], img_objs, &space);
   1435 		if (width_until_prev == ERROR) {
   1436 			DEBUG("line_width_until_text_above failed.");
   1437 			return false;
   1438 		}
   1439 		prev_width = text_above_width(ctx, text_above[i]);
   1440 		if (prev_width == ERROR) {
   1441 			DEBUG("text_above_width failed.");
   1442 			return false;
   1443 		}
   1444 		i++;
   1445 		width_between = width_until_cur - width_until_prev;
   1446 		if (prev_width + MIN_CHORD_GAP_WIDTH >= width_between) {
   1447 			space.text_above_index = i;
   1448 			space.amount = prev_width - width_between + MIN_CHORD_GAP_WIDTH;
   1449 			*spaces = erealloc(*spaces, (sp+1) * sizeof(struct SpaceNeeded *));
   1450 			(*spaces)[sp] = emalloc(sizeof(struct SpaceNeeded));
   1451 			*((*spaces)[sp]) = space;
   1452 			sp++;
   1453 		} else {
   1454 		}
   1455 	}
   1456 	*spaces = erealloc(*spaces, (sp+1) * sizeof(struct SpaceNeeded *));
   1457 	(*spaces)[sp] = NULL;
   1458 	return true;
   1459 }
   1460 
   1461 static double
   1462 item_width(
   1463 	struct PDFContext *ctx,
   1464 	struct ChoLineItem *item,
   1465 	int i,
   1466 	struct SpaceNeeded **spaces,
   1467 	struct Obj **img_objs
   1468 )
   1469 {
   1470 	char *name;
   1471 	double width;
   1472 	pdfio_obj_t *obj;
   1473 	struct SpaceNeeded **s;
   1474 
   1475 	if (item->is_text) {
   1476 		width = text_width(ctx, item->u.text->text, item->u.text->style);
   1477 		if (width == ERROR) {
   1478 			DEBUG("text_width failed.");
   1479 			return ERROR;
   1480 		}
   1481 		if (spaces) {
   1482 			for (s = spaces; *s; s++) {
   1483 				if ((*s)->line_item_index == i) {
   1484 					width += (*s)->amount;
   1485 				}
   1486 			}
   1487 		}
   1488 	} else {
   1489 		name = image_name(ctx, item->u.image);
   1490 		if (!name) {
   1491 			DEBUG("image_name failed.");
   1492 			return ERROR;
   1493 		}
   1494 		obj = objs_get_obj(img_objs, name);
   1495 		if (!obj) {
   1496 			DEBUG("objs_get_obj failed.");
   1497 			free(name);
   1498 			return ERROR;
   1499 		}
   1500 		free(name);
   1501 		width = image_width(item->u.image, obj);
   1502 	}
   1503 	return width;
   1504 }
   1505 
   1506 static struct CharPosition *
   1507 items_find_position_to_break_line(
   1508 	struct PDFContext *ctx,
   1509 	struct ChoLineItem **items,
   1510 	struct SpaceNeeded **spaces,
   1511 	struct Obj **img_objs
   1512 )
   1513 {
   1514 	int i;
   1515 	double d;
   1516 	double width = 0.0;
   1517 	struct CharPosition *pos;
   1518 
   1519 	pos = emalloc(sizeof(struct CharPosition));
   1520 	pos->line_item_index = EMPTY_INT;
   1521 	pos->text_index = EMPTY_INT;
   1522 	for (i = 0; items[i]; i++) {
   1523 		d = item_width(ctx, items[i], i, spaces, img_objs);
   1524 		if (d == ERROR) {
   1525 			DEBUG("item_width failed.");
   1526 			goto ERR;
   1527 		}
   1528 		if (width + d > LINE_WIDTH) {
   1529 			if (items[i]->is_text) {
   1530 				pos->line_item_index = i;
   1531 				pos->text_index = text_find_fitting(
   1532 					ctx,
   1533 					items[i]->u.text->text,
   1534 					items[i]->u.text->style,
   1535 					width,
   1536 					LINE_WIDTH
   1537 				);
   1538 				if (pos->text_index == EMPTY_INT) {
   1539 					DEBUG("text_find_fitting failed.");
   1540 					goto ERR;
   1541 				}
   1542 			} else {
   1543 				pos->line_item_index = i;
   1544 				pos->text_index = -1;
   1545 			}
   1546 			return pos;
   1547 		} else {
   1548 			width += d;
   1549 		}
   1550 	}
   1551 	return pos;
   1552 	ERR:
   1553 	free(pos);
   1554 	return NULL;
   1555 }
   1556 
   1557 static double
   1558 images_find_biggest_height(
   1559 	struct PDFContext *ctx,
   1560 	struct ChoLineItem **left_items,
   1561 	int line_item_index,
   1562 	struct Obj **img_objs
   1563 )
   1564 {
   1565 	struct ChoLineItem **it;
   1566 	pdfio_obj_t *obj;
   1567 	char *name;
   1568 	int i = 0;
   1569 	double end = line_item_index;
   1570 	double biggest = 0.0;
   1571 	double height;
   1572 
   1573 	// TODO: Why 10000?
   1574 	if (end == -1) {
   1575 		end = 10000;
   1576 	}
   1577 	for (it = left_items; *it && i <= end; it++, i++) {
   1578 		if (!(*it)->is_text) {
   1579 			name = image_name(ctx, (*it)->u.image);
   1580 			if (!name) {
   1581 				DEBUG("image_name failed.");
   1582 				return ERROR;
   1583 			}
   1584 			obj = objs_get_obj(img_objs, name);
   1585 			if (!obj) {
   1586 				DEBUG("objs_get_obj failed.");
   1587 				free(name);
   1588 				return ERROR;
   1589 			}
   1590 			height = image_height((*it)->u.image, obj);
   1591 			if (height > biggest) {
   1592 				biggest = height;
   1593 			}
   1594 			free(name);
   1595 		}
   1596 	}
   1597 	return biggest;
   1598 }
   1599 
   1600 static int
   1601 text_above_find_index_to_break_line(
   1602 	struct ChoLineItem **items,
   1603 	struct ChoLineItemAbove **text_above,
   1604 	struct CharPosition *pos
   1605 )
   1606 {
   1607 	int position = 0;
   1608 	int i, k;
   1609 
   1610 	if (pos->text_index == -1) {
   1611 		for (i = 0; items[i]; i++) {
   1612 			if (pos->line_item_index == i) {
   1613 				goto FOUND;
   1614 			}
   1615 			if (items[i]->is_text) {
   1616 				for (k = 0; items[i]->u.text->text[k]; k++) {
   1617 					position++;
   1618 				}
   1619 			}
   1620 		}
   1621 	} else {
   1622 		for (i = 0; items[i]; i++) {
   1623 			if (items[i]->is_text) {
   1624 				for (k = 0; items[i]->u.text->text[k]; k++) {
   1625 					if (pos->line_item_index == i && pos->text_index == k) {
   1626 						goto FOUND;
   1627 					}
   1628 					position++;
   1629 				}
   1630 			}
   1631 		}
   1632 	}
   1633 	return -2;
   1634 	FOUND:
   1635 	for (i = 0; text_above[i]; i++) {
   1636 		if (text_above[i]->position >= position) {
   1637 			return i;
   1638 		}
   1639 	}
   1640 	return -1;
   1641 }
   1642 
   1643 static void
   1644 text_above_update_positions(struct ChoLineItemAbove **aboves, size_t consumed_lyrics)
   1645 {
   1646 	struct ChoLineItemAbove **a;
   1647 	for (a = aboves; *a; a++) {
   1648 		(*a)->position -= consumed_lyrics + 1; // why plus one?
   1649 	}
   1650 }
   1651 
   1652 static double
   1653 calc_x(double width, enum Alignment align)
   1654 {
   1655 	if (align == ALIGNMENT_CENTER) {
   1656 		return MARGIN_HORIZONTAL + (LINE_WIDTH - width) / 2;
   1657 	}
   1658 	return MARGIN_HORIZONTAL;
   1659 }
   1660 
   1661 static const char *
   1662 handle_index(int index, char a, char b, char c)
   1663 {
   1664 	int i = 0;
   1665 	static char str[16];
   1666 
   1667 	memset(&str, 0, sizeof(str));
   1668 	switch (index) {
   1669 	case 1:
   1670 		str[i++] = a;
   1671 		break;
   1672 	case 2:
   1673 		str[i++] = a;
   1674 		str[i++] = a;
   1675 		break;
   1676 	case 3:
   1677 		str[i++] = a;
   1678 		str[i++] = a;
   1679 		str[i++] = a;
   1680 		break;
   1681 	case 4:
   1682 		str[i++] = a;
   1683 		str[i++] = b;
   1684 		break;
   1685 	case 5:
   1686 		str[i++] = b;
   1687 		break;
   1688 	case 6:
   1689 		str[i++] = b;
   1690 		str[i++] = a;
   1691 		break;
   1692 	case 7:
   1693 		str[i++] = b;
   1694 		str[i++] = a;
   1695 		str[i++] = a;
   1696 		break;
   1697 	case 8:
   1698 		str[i++] = b;
   1699 		str[i++] = a;
   1700 		str[i++] = a;
   1701 		str[i++] = a;
   1702 		break;
   1703 	case 9:
   1704 		str[i++] = a;
   1705 		str[i++] = c;
   1706 	}
   1707 	str[i] = 0;
   1708 	return str;
   1709 }
   1710 
   1711 static const char *
   1712 numeral_system_western_arabic_to_roman(unsigned int n)
   1713 {
   1714 	if (n > 999) {
   1715 		util_log(NULL, 0, LOG_ERR, "Converting numbers higher than 999 is not supported.");
   1716 		return NULL;
   1717 	}
   1718 	const char *str;
   1719 	static char roman[64];
   1720 	int k;
   1721 	int r = 0;
   1722 	char i = 'I';
   1723 	char v = 'V';
   1724 	char x = 'X';
   1725 	char l = 'L';
   1726 	char c = 'C';
   1727 	char d = 'D';
   1728 	char m = 'M';
   1729 	int index_0 = n - n / 10 * 10;
   1730 	int index_1 = (n - n / 100 * 100 - index_0) / 10;
   1731 	int index_2 = (n - n / 1000 * 1000 - index_0 - index_1) / 100;
   1732 	if (index_2 > 0) {
   1733 		str = handle_index(index_2, c, d, m);
   1734 		for (k = 0; str[k]; k++, r++) {
   1735 			roman[r] = str[k];
   1736 		}
   1737 	}
   1738 	if (index_1 > 0) {
   1739 		str = handle_index(index_1, x, l, c);
   1740 		for (k = 0; str[k]; k++, r++) {
   1741 			roman[r] = str[k];
   1742 		}
   1743 	}
   1744 	if (index_0 > 0) {
   1745 		str = handle_index(index_0, i, v, x);
   1746 		for (k = 0; str[k]; k++, r++) {
   1747 			roman[r] = str[k];
   1748 		}
   1749 	}
   1750 	roman[r] = 0;
   1751 	return roman;
   1752 }
   1753 
   1754 static const char *
   1755 numeral_system_number_to_str(enum NumeralSystem system, int n)
   1756 {
   1757 	if (system == NUMERAL_SYSTEM_ROMAN) {
   1758 		const char *str = numeral_system_western_arabic_to_roman((unsigned int)n);
   1759 		if (!str) {
   1760 			DEBUG("numeral_system_western_arabic_to_roman failed.");
   1761 			return NULL;
   1762 		}
   1763 		return str;
   1764 	} else {
   1765 		static char str[11+1];
   1766 		snprintf((char *)&str, 11+1, "%d", n);
   1767 		return str;
   1768 	}
   1769 }
   1770 
   1771 static bool
   1772 pdf_page_add_page_no(
   1773 	struct PDFContext *ctx,
   1774 	struct PDFContentContext *c_ctx,
   1775 	enum NumeralSystem numeral_system
   1776 )
   1777 {
   1778 	struct PDFText ***texts;
   1779 	struct ChoStyle *style;
   1780 	const char *page_no;
   1781 	double width, x;
   1782 
   1783 	style = cho_style_new();
   1784 	style->font->family = strdup(DEFAULT_FONT);
   1785 	texts = &c_ctx->content->pages[c_ctx->page]->texts;
   1786 	page_no = numeral_system_number_to_str(numeral_system, c_ctx->page+1);
   1787 	if (!page_no) {
   1788 		DEBUG("numeral_system_number_to_str failed.");
   1789 		cho_style_free(style);
   1790 		return false;
   1791 	}
   1792 	width = text_width(ctx, page_no, style);
   1793 	if (width == ERROR) {
   1794 		DEBUG("text_width failed.");
   1795 		cho_style_free(style);
   1796 		return false;
   1797 	}
   1798 	*texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
   1799 	(*texts)[c_ctx->text] = pdf_text_new();
   1800 	(*texts)[c_ctx->text]->text = strdup(page_no);
   1801 	(*texts)[c_ctx->text]->style = style;
   1802 	(*texts)[c_ctx->text]->x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width;
   1803 	(*texts)[c_ctx->text]->y = MARGIN_BOTTOM / 2;
   1804 	(*texts)[c_ctx->text]->width = width;
   1805 	switch (ctx->config->output->page_no->align) {
   1806 	case ALIGNMENT_LEFT:
   1807 		x = MARGIN_HORIZONTAL / 2;
   1808 		break;
   1809 	case ALIGNMENT_CENTER:
   1810 		x = MARGIN_HORIZONTAL + (LINE_WIDTH - width) / 2;
   1811 		break;
   1812 	case ALIGNMENT_RIGHT:
   1813 		x = MEDIABOX_WIDTH - MARGIN_HORIZONTAL / 2 - width;
   1814 		break;
   1815 	default:
   1816 		util_log(NULL, 0, LOG_ERR, "Invalid Alignment enum value '%d'.", ctx->config->output->page_no->align);
   1817 		return false;
   1818 	}
   1819 	(*texts)[c_ctx->text]->x = x;
   1820 	c_ctx->text++;
   1821 	return true;
   1822 }
   1823 
   1824 static bool
   1825 pdf_page_close_then_add(
   1826 	struct PDFContext *ctx,
   1827 	struct PDFContentContext *c_ctx,
   1828 	enum NumeralSystem numeral_system
   1829 )
   1830 {
   1831 	c_ctx->content->pages[c_ctx->page]->texts = erealloc(
   1832 		c_ctx->content->pages[c_ctx->page]->texts,
   1833 		(c_ctx->text+1) * sizeof(struct PDFText *)
   1834 	);
   1835 	c_ctx->content->pages[c_ctx->page]->texts[c_ctx->text] = NULL;
   1836 	c_ctx->content->pages[c_ctx->page]->images = erealloc(
   1837 		c_ctx->content->pages[c_ctx->page]->images,
   1838 		(c_ctx->image+1) * sizeof(struct PDFImage *)
   1839 	);
   1840 	c_ctx->content->pages[c_ctx->page]->images[c_ctx->image] = NULL;
   1841 	c_ctx->content->pages[c_ctx->page]->diagrams = erealloc(
   1842 		c_ctx->content->pages[c_ctx->page]->diagrams,
   1843 		(c_ctx->diagram+1) * sizeof(struct ChordDiagram *)
   1844 	);
   1845 	c_ctx->content->pages[c_ctx->page]->diagrams[c_ctx->diagram] = NULL;
   1846 	c_ctx->text = 0;
   1847 	c_ctx->image = 0;
   1848 	c_ctx->diagram = 0;
   1849 	c_ctx->page++;
   1850 	c_ctx->content->pages = erealloc(c_ctx->content->pages, (c_ctx->page+1) * sizeof(struct PDFPage *));
   1851 	c_ctx->content->pages[c_ctx->page] = pdf_page_new(ctx);
   1852 	c_ctx->y = MEDIABOX_HEIGHT - MARGIN_TOP;
   1853 	if (ctx->config->output->page_no->show) {
   1854 		if (!pdf_page_add_page_no(ctx, c_ctx, numeral_system)) {
   1855 			DEBUG("pdf_page_add_page_no failed.");
   1856 			return false;
   1857 		}
   1858 	}
   1859 	return true;
   1860 }
   1861 
   1862 static int
   1863 pdf_toc_page_count(
   1864 	struct PDFContext *ctx,
   1865 	struct TocEntry **entries,
   1866 	struct ChoStyle *style,
   1867 	double max_title_width
   1868 )
   1869 {
   1870 	int index;
   1871 	int page = 0;
   1872 	double y = MEDIABOX_HEIGHT - MARGIN_TOP;
   1873 	double width;
   1874 	char *t;
   1875 	struct TocEntry **toc;
   1876 
   1877 	for (toc = entries; *toc; toc++) {
   1878 		char tmp[strlen((*toc)->title)+1];
   1879 
   1880 		if (y < MARGIN_BOTTOM) {
   1881 			y = MEDIABOX_HEIGHT - MARGIN_TOP;
   1882 			page++;
   1883 		}
   1884 		strcpy((char *)&tmp, (*toc)->title);
   1885 		width = text_width(ctx, (*toc)->title, style);
   1886 		if (width == ERROR) {
   1887 			DEBUG("text_width failed.");
   1888 			return -1;
   1889 		}
   1890 		width += MARGIN_HORIZONTAL;
   1891 		if (width > max_title_width) {
   1892 			t = (char *)&tmp;
   1893 			while (width > max_title_width) {
   1894 				index = text_find_fitting(ctx, t, style, MARGIN_HORIZONTAL, max_title_width);
   1895 				if (index == EMPTY_INT) {
   1896 					DEBUG("text_find_fitting failed.");
   1897 					return -1;
   1898 				}
   1899 				t[index] = 0;
   1900 				y -= 8.0 + style->font->size;
   1901 				t += index + 1;
   1902 				width = text_width(ctx, t, style);
   1903 				if (width == ERROR) {
   1904 					DEBUG("text_width failed.");
   1905 					return -1;
   1906 				}
   1907 			}
   1908 			y -= 8.0 + style->font->size;
   1909 		} else {
   1910 			y -= 8.0 + style->font->size;
   1911 		}
   1912 	}
   1913 	return page + 1;
   1914 }
   1915 
   1916 static const char *
   1917 toc_dots_create(double available_width, double dot_width)
   1918 {
   1919 	available_width -= MARGIN_HORIZONTAL;
   1920 	int dot_count;
   1921 	static char dots[1024];
   1922 	dot_count = (int)floor(available_width / dot_width);
   1923 	if (dot_count > 1023) {
   1924 		return NULL;
   1925 	}
   1926 	memset(&dots, (int)'.', dot_count);
   1927 	dots[dot_count+1] = 0;
   1928 	return dots;
   1929 }
   1930 
   1931 // HERE
   1932 static bool
   1933 pdf_texts_add_toc_entry(
   1934 	struct PDFContext *ctx,
   1935 	struct TocEntry *entry,
   1936 	struct ChoStyle *style,
   1937 	double max_song_title_width,
   1938 	int toc_page_count,
   1939 	double dot_width
   1940 )
   1941 {
   1942 	struct PDFText ***texts;
   1943 	double width, page_no_x, end_of_title_x, width_between_title_and_page_no, available_dots_width;
   1944 	double page_no_width, dots_width;
   1945 	int index, line_count;
   1946 	char tmp[strlen(entry->title)+1];
   1947 	size_t page_no_size = 11 + 1;
   1948 	char page_no[page_no_size];
   1949 
   1950 	texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   1951 	strcpy((char *)&tmp, entry->title);
   1952 	width = text_width(ctx, entry->title, style);
   1953 	if (width == ERROR) {
   1954 		DEBUG("text_width failed.");
   1955 		return false;
   1956 	}
   1957 	if (width+MARGIN_HORIZONTAL > max_song_title_width) {
   1958 		char *t = (char *)&tmp;
   1959 		line_count = 0;
   1960 		while (width+MARGIN_HORIZONTAL > max_song_title_width) {
   1961 			if (ctx->t_ctx.y < MARGIN_BOTTOM) {
   1962 				if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUMERAL_SYSTEM_ROMAN)) {
   1963 					DEBUG("pdf_page_close_then_add failed.");
   1964 					return false;
   1965 				}
   1966 				texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   1967 			}
   1968 			index = text_find_fitting(ctx, t, style, MARGIN_HORIZONTAL, max_song_title_width);
   1969 			if (index == EMPTY_INT) {
   1970 				DEBUG("text_find_fitting failed.");
   1971 				return false;
   1972 			}
   1973 			t[index] = 0;
   1974 			*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   1975 			(*texts)[ctx->t_ctx.text] = pdf_text_new();
   1976 			(*texts)[ctx->t_ctx.text]->text = strdup(t);
   1977 			(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   1978 			(*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
   1979 			(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   1980 			ctx->t_ctx.y -= 8.0 + style->font->size;
   1981 			line_count++;
   1982 			width = text_width(ctx, t, style);
   1983 			if (width == ERROR) {
   1984 				DEBUG("text_width failed.");
   1985 				return false;
   1986 			}
   1987 			(*texts)[ctx->t_ctx.text]->width = width;
   1988 			t += index + 1;
   1989 			width = text_width(ctx, t, style);
   1990 			if (width == ERROR) {
   1991 				DEBUG("text_width failed.");
   1992 				return false;
   1993 			}
   1994 			ctx->t_ctx.text++;
   1995 		}
   1996 		if (ctx->t_ctx.y < MARGIN_BOTTOM) {
   1997 			if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUMERAL_SYSTEM_ROMAN)) {
   1998 				DEBUG("pdf_page_close_then_add failed.");
   1999 				return false;
   2000 			}
   2001 			texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   2002 		}
   2003 		end_of_title_x = width;
   2004 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2005 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2006 		(*texts)[ctx->t_ctx.text]->text = strdup(t);
   2007 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2008 		(*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
   2009 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2010 		(*texts)[ctx->t_ctx.text]->width = width;
   2011 		ctx->t_ctx.text++;
   2012 		snprintf((char *)&page_no, page_no_size, "%d", entry->page_index+1);
   2013 		width = text_width(ctx, page_no, style);
   2014 		if (width == ERROR) {
   2015 			DEBUG("text_width failed.");
   2016 			return false;
   2017 		}
   2018 
   2019 		page_no_x = MEDIABOX_WIDTH - width - MARGIN_HORIZONTAL;
   2020 		width_between_title_and_page_no = page_no_x - end_of_title_x;
   2021 		available_dots_width = width_between_title_and_page_no - TOC_DOTS_GAP_WIDTH*2;
   2022 		const char *dots = toc_dots_create(available_dots_width, dot_width);
   2023 		if (!dots) {
   2024 			DEBUG("toc_dots_create failed.");
   2025 			return false;
   2026 		}
   2027 
   2028 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2029 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2030 		(*texts)[ctx->t_ctx.text]->text = strdup(dots);
   2031 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2032 		(*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
   2033 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2034 		ctx->t_ctx.text++;
   2035 
   2036 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2037 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2038 		(*texts)[ctx->t_ctx.text]->text = strdup(page_no);
   2039 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2040 		(*texts)[ctx->t_ctx.text]->x = page_no_x;
   2041 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2042 		(*texts)[ctx->t_ctx.text]->width = width;
   2043 		line_count++;
   2044 		if (!annot_page_link_add(ctx, entry, toc_page_count, line_count, style->font->size)) {
   2045 			DEBUG("annot_page_link_add");
   2046 			return false;
   2047 		}
   2048 		ctx->t_ctx.text++;
   2049 		ctx->t_ctx.y -= 8.0 + style->font->size;
   2050 	} else {
   2051 		if (ctx->t_ctx.y < MARGIN_BOTTOM) {
   2052 			if (!pdf_page_close_then_add(ctx, &ctx->t_ctx, NUMERAL_SYSTEM_ROMAN)) {
   2053 				DEBUG("pdf_page_close_then_add failed.");
   2054 				return false;
   2055 			}
   2056 			texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   2057 		}
   2058 		end_of_title_x = width;
   2059 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2060 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2061 		(*texts)[ctx->t_ctx.text]->text = strdup(entry->title);
   2062 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2063 		(*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL;
   2064 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2065 		width = text_width(ctx, entry->title, style);
   2066 		if (width == ERROR) {
   2067 			DEBUG("text_width failed.");
   2068 			return false;
   2069 		}
   2070 		(*texts)[ctx->t_ctx.text]->width = width;
   2071 		ctx->t_ctx.text++;
   2072 		snprintf((char *)&page_no, page_no_size, "%d", entry->page_index+1);
   2073 		page_no_width = text_width(ctx, page_no, style);
   2074 		if (page_no_width == ERROR) {
   2075 			DEBUG("text_width failed.");
   2076 			return false;
   2077 		}
   2078 
   2079 		page_no_x = MEDIABOX_WIDTH - page_no_width - MARGIN_HORIZONTAL;
   2080 		width_between_title_and_page_no = page_no_x - end_of_title_x;
   2081 		available_dots_width = width_between_title_and_page_no - TOC_DOTS_GAP_WIDTH*2;
   2082 		const char *dots = toc_dots_create(available_dots_width, dot_width);
   2083 		if (!dots) {
   2084 			DEBUG("toc_dots_create failed.");
   2085 			return false;
   2086 		}
   2087 		dots_width = text_width(ctx, dots, style);
   2088 		if (dots_width == ERROR) {
   2089 			DEBUG("text_width failed.");
   2090 			return false;
   2091 		}
   2092 
   2093 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2094 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2095 		(*texts)[ctx->t_ctx.text]->text = strdup(dots);
   2096 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2097 		(*texts)[ctx->t_ctx.text]->x = MARGIN_HORIZONTAL + end_of_title_x + TOC_DOTS_GAP_WIDTH;
   2098 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2099 		(*texts)[ctx->t_ctx.text]->width = dots_width;
   2100 		ctx->t_ctx.text++;
   2101 
   2102 		*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2103 		(*texts)[ctx->t_ctx.text] = pdf_text_new();
   2104 		(*texts)[ctx->t_ctx.text]->text = strdup(page_no);
   2105 		(*texts)[ctx->t_ctx.text]->style = cho_style_copy(style);
   2106 		(*texts)[ctx->t_ctx.text]->x = page_no_x;
   2107 		(*texts)[ctx->t_ctx.text]->y = ctx->t_ctx.y;
   2108 		(*texts)[ctx->t_ctx.text]->width = page_no_width;
   2109 		if (!annot_page_link_add(ctx, entry, toc_page_count, 1, style->font->size)) {
   2110 			DEBUG("annot_page_link_add");
   2111 			return false;
   2112 		}
   2113 		ctx->t_ctx.text++;
   2114 		ctx->t_ctx.y -= 8.0 + style->font->size;
   2115 	}
   2116 	return true;
   2117 }
   2118 
   2119 static bool
   2120 pdf_texts_add_lyrics(
   2121 	struct PDFContext *ctx,
   2122 	struct ChoLineItem *item,
   2123 	int i
   2124 )
   2125 {
   2126 	struct PDFText ***texts;
   2127 	struct SpaceNeeded **sp;
   2128 	double width;
   2129 	int t = 0;
   2130 	int c;
   2131 
   2132 	texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2133 	*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2134 	(*texts)[ctx->b_ctx.text] = pdf_text_new();
   2135 	if (!ctx->b_ctx.spaces) {
   2136 		(*texts)[ctx->b_ctx.text]->text = strdup(item->u.text->text);
   2137 		(*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
   2138 		(*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
   2139 		(*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
   2140 		width = text_width(ctx, item->u.text->text, item->u.text->style);
   2141 		if (width == ERROR) {
   2142 			DEBUG("text_width failed.");
   2143 			return false;
   2144 		}
   2145 		(*texts)[ctx->b_ctx.text]->width = width;
   2146 		if (item->u.text->style->href) {
   2147 			if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
   2148 				DEBUG("annot_url_link_add failed.");
   2149 				return false;
   2150 			}
   2151 		}
   2152 		ctx->b_ctx.x += width;
   2153 		if ((*texts)[ctx->b_ctx.text]->style->font->size > ctx->b_ctx.biggest_font_size) {
   2154 			ctx->b_ctx.biggest_font_size = (*texts)[ctx->b_ctx.text]->style->font->size;
   2155 		}
   2156 		ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
   2157 		ctx->b_ctx.text++;
   2158 		return true;
   2159 	}
   2160 	for (c = 0; item->u.text->text[c]; c++) {
   2161 		(*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
   2162 		(*texts)[ctx->b_ctx.text]->text[t] = item->u.text->text[c];
   2163 		t++;
   2164 		for (sp = ctx->b_ctx.spaces; *sp; sp++) {
   2165 			if ((*sp)->line_item_index == i && (*sp)->text_index == c) {
   2166 				size_t len = grapheme_next_character_break_utf8(&item->u.text->text[c], 10);
   2167 				size_t i;
   2168 				for (i = 0; i<len-1; i++, t++) {
   2169 					c++;
   2170 					(*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
   2171 					(*texts)[ctx->b_ctx.text]->text[t] = item->u.text->text[c];
   2172 				}
   2173 				(*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
   2174 				(*texts)[ctx->b_ctx.text]->text[t] = 0;
   2175 				(*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
   2176 				(*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
   2177 				(*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
   2178 				width = text_width(ctx, (*texts)[ctx->b_ctx.text]->text, item->u.text->style);
   2179 				if (width == ERROR) {
   2180 					DEBUG("text_width failed.");
   2181 					return false;
   2182 				}
   2183 				(*texts)[ctx->b_ctx.text]->width = width;
   2184 				if (item->u.text->style->href) {
   2185 					if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
   2186 						DEBUG("annot_url_link_add failed.");
   2187 						return false;
   2188 					}
   2189 				}
   2190 				ctx->b_ctx.x += width;
   2191 				ctx->b_ctx.x += (*sp)->amount;
   2192 				t = 0;
   2193 				ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
   2194 				ctx->b_ctx.text++;
   2195 				*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2196 				(*texts)[ctx->b_ctx.text] = pdf_text_new();
   2197 			}
   2198 		}
   2199 	}
   2200 	(*texts)[ctx->b_ctx.text]->text = erealloc((*texts)[ctx->b_ctx.text]->text, (t+1) * sizeof(char));
   2201 	(*texts)[ctx->b_ctx.text]->text[t] = 0;
   2202 	(*texts)[ctx->b_ctx.text]->style = cho_style_copy(item->u.text->style);
   2203 	(*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
   2204 	(*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
   2205 	width = text_width(ctx, (*texts)[ctx->b_ctx.text]->text, item->u.text->style);
   2206 	if (width == ERROR) {
   2207 		DEBUG("text_width failed.");
   2208 		return false;
   2209 	}
   2210 	(*texts)[ctx->b_ctx.text]->width = width;
   2211 	if (item->u.text->style->href) {
   2212 		if (!annot_url_link_add(ctx, &ctx->b_ctx, item->u.text->style, width)) {
   2213 			DEBUG("annot_url_link_add failed.");
   2214 			return false;
   2215 		}
   2216 	}
   2217 	ctx->b_ctx.x += width;
   2218 	if ((*texts)[ctx->b_ctx.text]->style->font->size > ctx->b_ctx.biggest_font_size) {
   2219 		ctx->b_ctx.biggest_font_size = (*texts)[ctx->b_ctx.text]->style->font->size;
   2220 	}
   2221 	ctx->b_ctx.consumed_lyrics += strlen((*texts)[ctx->b_ctx.text]->text);
   2222 	ctx->b_ctx.text++;
   2223 	return true;
   2224 }
   2225 
   2226 static bool
   2227 pdf_texts_add_text(
   2228 	struct PDFContext *ctx,
   2229 	struct PDFContentContext *c_ctx,
   2230 	const char *text,
   2231 	struct ChoStyle *style,
   2232 	enum Alignment align,
   2233 	enum NumeralSystem numeral_system
   2234 )
   2235 {
   2236 	struct PDFText ***texts;
   2237 	char str[strlen(text)+1];
   2238 	double width;
   2239 	int index;
   2240 
   2241 	strcpy((char *)&str, text);
   2242 	texts = &c_ctx->content->pages[c_ctx->page]->texts;
   2243 	width = text_width(ctx, text, style);
   2244 	if (width == ERROR) {
   2245 		DEBUG("text_width failed.");
   2246 		return false;
   2247 	}
   2248 	if (width > LINE_WIDTH) {
   2249 		char *t = (char *)&str;
   2250 		while (width > LINE_WIDTH) {
   2251 			if (c_ctx->y < c_ctx->margin_bottom) {
   2252 				if (!pdf_page_close_then_add(ctx, c_ctx, numeral_system)) {
   2253 					DEBUG("pdf_page_close_then_add failed.");
   2254 					return false;
   2255 				}
   2256 				texts = &c_ctx->content->pages[c_ctx->page]->texts;
   2257 			}
   2258 			index = text_find_fitting(ctx, t, style, 0.0, LINE_WIDTH);
   2259 			if (index == EMPTY_INT) {
   2260 				DEBUG("text_find_fitting failed.");
   2261 				return false;
   2262 			}
   2263 			t[index] = 0;
   2264 			width = text_width(ctx, t, style);
   2265 			if (width == ERROR) {
   2266 				DEBUG("text_width failed.");
   2267 				return false;
   2268 			}
   2269 			c_ctx->x = calc_x(width, align);
   2270 			*texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
   2271 			(*texts)[c_ctx->text] = pdf_text_new();
   2272 			(*texts)[c_ctx->text]->text = strdup(t);
   2273 			(*texts)[c_ctx->text]->style = cho_style_copy(style);
   2274 			(*texts)[c_ctx->text]->x = c_ctx->x;
   2275 			(*texts)[c_ctx->text]->y = c_ctx->y;
   2276 			(*texts)[c_ctx->text]->width = width;
   2277 			if (style->href) {
   2278 				if (!annot_url_link_add(ctx, c_ctx, style, width)) {
   2279 					DEBUG("annot_url_link_add failed.");
   2280 					return false;
   2281 				}
   2282 			}
   2283 			c_ctx->text++;
   2284 			c_ctx->y -= 8.0 + style->font->size;
   2285 			t += index+1;
   2286 			width = text_width(ctx, t, style);
   2287 			if (width == ERROR) {
   2288 				DEBUG("text_width failed.");
   2289 				return false;
   2290 			}
   2291 		}
   2292 		width = text_width(ctx, t, style);
   2293 		if (width == ERROR) {
   2294 			DEBUG("text_width failed.");
   2295 			return false;
   2296 		}
   2297 		c_ctx->x = calc_x(width, align);
   2298 		*texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
   2299 		(*texts)[c_ctx->text] = pdf_text_new();
   2300 		(*texts)[c_ctx->text]->text = strdup(t);
   2301 		(*texts)[c_ctx->text]->style = cho_style_copy(style);
   2302 		(*texts)[c_ctx->text]->x = c_ctx->x;
   2303 		(*texts)[c_ctx->text]->y = c_ctx->y;
   2304 		(*texts)[c_ctx->text]->width = width;
   2305 		if (style->href) {
   2306 			if (!annot_url_link_add(ctx, c_ctx, style, width)) {
   2307 				DEBUG("annot_url_link_add failed.");
   2308 				return false;
   2309 			}
   2310 		}
   2311 		c_ctx->text++;
   2312 		c_ctx->y -= 8.0 + style->font->size;
   2313 	} else {
   2314 		if (c_ctx->y < c_ctx->margin_bottom) {
   2315 			if (!pdf_page_close_then_add(ctx, c_ctx, numeral_system)) {
   2316 				DEBUG("pdf_page_close_then_add failed.");
   2317 				return false;
   2318 			}
   2319 			texts = &c_ctx->content->pages[c_ctx->page]->texts;
   2320 		}
   2321 		c_ctx->x = calc_x(width, align);
   2322 		*texts = erealloc(*texts, (c_ctx->text+1) * sizeof(struct PDFText *));
   2323 		(*texts)[c_ctx->text] = pdf_text_new();
   2324 		(*texts)[c_ctx->text]->text = strdup(text);
   2325 		(*texts)[c_ctx->text]->style = cho_style_copy(style);
   2326 		(*texts)[c_ctx->text]->x = c_ctx->x;
   2327 		(*texts)[c_ctx->text]->y = c_ctx->y;
   2328 		(*texts)[c_ctx->text]->width = width;
   2329 		if (style->href) {
   2330 			if (!annot_url_link_add(ctx, c_ctx, style, width)) {
   2331 				DEBUG("annot_url_link_add failed.");
   2332 				return false;
   2333 			}
   2334 		}
   2335 		c_ctx->text++;
   2336 		c_ctx->y -= 8.0 + style->font->size;
   2337 	}
   2338 	return true;
   2339 }
   2340 
   2341 static double
   2342 find_biggest_line_item_width(struct PDFContext *ctx, struct ChoLine **lines)
   2343 {
   2344 	struct ChoLine **li;
   2345 	struct ChoLineItem **lii;
   2346 	double width;
   2347 	double biggest = 0.0;
   2348 
   2349 	for (li = lines; *li; li++) {
   2350 		for (lii = (*li)->items; *lii; lii++) {
   2351 			width = text_width(ctx, (*lii)->u.text->text, (*lii)->u.text->style);
   2352 			if (width == -1) {
   2353 				DEBUG("text_width failed.");
   2354 				return -1;
   2355 			}
   2356 			if (width > biggest) {
   2357 				biggest = width;
   2358 			}
   2359 		}
   2360 	}
   2361 	return biggest;
   2362 }
   2363 
   2364 static bool
   2365 pdf_toc_create(
   2366 	struct PDFContext *ctx,
   2367 	struct PDFContent *pdf_body,
   2368 	struct PDFContent **out
   2369 )
   2370 {
   2371 	double max_song_title_width, dot_width;
   2372 	int toc_page_count;
   2373 	struct PDFText ***texts;
   2374 	struct ChoStyle *toc_style, *title_style;
   2375 	struct TocEntry **toc;
   2376 
   2377 	pdf_content_context_init(&ctx->t_ctx);
   2378 	ctx->t_ctx.content = pdf_content_new();
   2379 	ctx->t_ctx.content->pages = emalloc(sizeof(struct PDFPage *));
   2380 	ctx->t_ctx.content->pages[ctx->t_ctx.page] = pdf_page_new(ctx);
   2381 	texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   2382 	if (ctx->config->output->page_no->show) {
   2383 		if (!pdf_page_add_page_no(ctx, &ctx->t_ctx, NUMERAL_SYSTEM_ROMAN)) {
   2384 			DEBUG("pdf_page_add_page_no failed.");
   2385 			return false;
   2386 		}
   2387 	}
   2388 	toc_style = ctx->config->output->styles[TEXT_TYPE_TOC];
   2389 	toc = pdf_body->toc;
   2390 	max_song_title_width = LINE_WIDTH * 0.85;
   2391 	toc_page_count = pdf_toc_page_count(ctx, toc, toc_style, max_song_title_width);
   2392 	if (toc_page_count == -1) {
   2393 		DEBUG("pdf_toc_page_count failed.");
   2394 		return false;
   2395 	}
   2396 	title_style = ctx->config->output->styles[TEXT_TYPE_TOC_TITLE];
   2397 	if (!pdf_texts_add_text(ctx, &ctx->t_ctx, ctx->config->output->toc->title, title_style, ALIGNMENT_CENTER, NUMERAL_SYSTEM_ROMAN)) {
   2398 		DEBUG("pdf_texts_add_text(toctitle) failed.");
   2399 		return false;
   2400 	}
   2401 	ctx->t_ctx.y -= 30.0;
   2402 	dot_width = text_width(ctx, ".", toc_style);
   2403 	if (dot_width == ERROR) {
   2404 		DEBUG("text_width failed.");
   2405 		return false;
   2406 	}
   2407 	for (; *toc; toc++) {
   2408 		if (!pdf_texts_add_toc_entry(ctx, *toc, toc_style, max_song_title_width, toc_page_count, dot_width)) {
   2409 			DEBUG("pdf_texts_add_toc_entry failed.");
   2410 			return false;
   2411 		}
   2412 	}
   2413 	texts = &ctx->t_ctx.content->pages[ctx->t_ctx.page]->texts;
   2414 	*texts = erealloc(*texts, (ctx->t_ctx.text+1) * sizeof(struct PDFText *));
   2415 	(*texts)[ctx->t_ctx.text] = NULL;
   2416 	ctx->t_ctx.page++;
   2417 	ctx->t_ctx.content->pages = erealloc(ctx->t_ctx.content->pages, (ctx->t_ctx.page+1) * sizeof(struct PDFPage *));
   2418 	ctx->t_ctx.content->pages[ctx->t_ctx.page] = NULL;
   2419 	*out = ctx->t_ctx.content;
   2420 	return true;
   2421 }
   2422 
   2423 static bool
   2424 pdf_body_create(
   2425 	struct PDFContext *ctx,
   2426 	struct ChoSong **songs,
   2427 	struct Obj **img_objs,
   2428 	struct PDFContent **out
   2429 )
   2430 {
   2431 	struct ChoSection **se;
   2432 	struct ChoLine **li;
   2433 	struct PDFText ***texts;
   2434 	struct PDFImage ***imgs;
   2435 	struct ChordDiagram ***diagrams, **dgrams, **d;
   2436 	struct ChoStyle *metadata_style;
   2437 	char *metadata;
   2438 	bool show_diagram = ctx->config->output->diagram->show;
   2439 	bool start_song_on_new_page = ctx->config->output->start_song_on_new_page;
   2440 	double width, height;
   2441 
   2442 	pdf_content_context_init(&ctx->b_ctx);
   2443 	if (show_diagram) {
   2444 		ctx->b_ctx.margin_bottom = 150.0;
   2445 	}
   2446 	ctx->b_ctx.content = pdf_content_new();
   2447 	ctx->b_ctx.content->pages = emalloc(sizeof(struct PDFPage *));
   2448 	ctx->b_ctx.content->pages[ctx->b_ctx.page] = pdf_page_new(ctx);
   2449 	texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2450 	imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2451 	diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2452 	if (ctx->config->output->page_no->show) {
   2453 		if (!pdf_page_add_page_no(ctx, &ctx->b_ctx, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2454 			DEBUG("pdf_page_add_page_no failed.");
   2455 			return false;
   2456 		}
   2457 	}
   2458 	int s;
   2459 	for (s = 0; songs[s]; s++) {
   2460 		if (show_diagram) {
   2461 			struct ChoChord **chords;
   2462 			chords = pdf_get_chords(songs[s]);
   2463 			if (chords) {
   2464 				qsort(chords, cho_chord_count(chords), sizeof(struct ChoChord *), cho_chord_compare);
   2465 				dgrams = chord_diagrams_create(ctx->config, &chords, songs[s]->diagrams);
   2466 				for (d = dgrams; *d; d++) {
   2467 					*diagrams = erealloc(*diagrams, (ctx->b_ctx.diagram+1) * sizeof(struct ChordDiagram *));
   2468 					(*diagrams)[ctx->b_ctx.diagram] = *d;
   2469 					ctx->b_ctx.diagram++;
   2470 				}
   2471 				free(dgrams);
   2472 				cho_chords_free(chords);
   2473 			}
   2474 		}
   2475 		if (!cho_metadata_value(songs[s]->metadata, "title", ctx->config->metadata_separator, &metadata, &metadata_style)) {
   2476 			DEBUG("cho_metadata_value failed.");
   2477 			return false;
   2478 		}
   2479 		ctx->b_ctx.content->toc = erealloc(ctx->b_ctx.content->toc, (ctx->b_ctx.toc_entry+1) * sizeof(struct TocEntry *));
   2480 		ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry] = emalloc(sizeof(struct TocEntry));
   2481 		ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->title = strdup(metadata);
   2482 		ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->page_index = ctx->b_ctx.page;
   2483 		ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry]->page_y = ctx->b_ctx.y;
   2484 		ctx->b_ctx.toc_entry++;
   2485 		if (!pdf_texts_add_text(ctx, &ctx->b_ctx, metadata, metadata_style, ALIGNMENT_CENTER, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2486 			DEBUG("pdf_texts_add_text(title) failed.");
   2487 			free(metadata);
   2488 			return false;
   2489 		}
   2490 		free(metadata);
   2491 		if (cho_metadata_value(songs[s]->metadata, "subtitle", ctx->config->metadata_separator, &metadata, &metadata_style)) {
   2492 			if (!pdf_texts_add_text(ctx, &ctx->b_ctx, metadata, metadata_style, ALIGNMENT_CENTER, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2493 				DEBUG("pdf_texts_add_text(subtitle) failed.");
   2494 				free(metadata);
   2495 				return false;
   2496 			}
   2497 			free(metadata);
   2498 		}
   2499 		texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2500 		imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2501 		diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2502 		ctx->b_ctx.y -= 30.0;
   2503 		for (se = songs[s]->sections; *se; se++) {
   2504 			if ((*se)->label) {
   2505 				if (!pdf_texts_add_text(ctx, &ctx->b_ctx, (*se)->label->text, (*se)->label->style, ALIGNMENT_LEFT, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2506 					DEBUG("pdf_texts_add_text(label) failed.");
   2507 					return false;
   2508 				}
   2509 				texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2510 				imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2511 				diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2512 			}
   2513 			if ((*se)->type == SECTION_TYPE_GRID) {
   2514 				double biggest_line_item_width, x, biggest_font_size;
   2515 				struct ChoLine **li;
   2516 				struct ChoLineItem **lii;
   2517 
   2518 				biggest_line_item_width = find_biggest_line_item_width(ctx, (*se)->lines);
   2519 				if (biggest_line_item_width == -1) {
   2520 					DEBUG("find_biggest_line_item_width failed.");
   2521 					return false;
   2522 				}
   2523 				for (li = (*se)->lines; *li; li++) {
   2524 					x = MARGIN_HORIZONTAL;
   2525 					biggest_font_size = 0.0;
   2526 					for (lii = (*li)->items; *lii; lii++) {
   2527 						if ((*lii)->u.text->style->font->size > biggest_font_size) {
   2528 							biggest_font_size = (*lii)->u.text->style->font->size;
   2529 						}
   2530 						*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2531 						(*texts)[ctx->b_ctx.text] = pdf_text_new();
   2532 						(*texts)[ctx->b_ctx.text]->text = strdup((*lii)->u.text->text);
   2533 						(*texts)[ctx->b_ctx.text]->style = cho_style_copy((*lii)->u.text->style);
   2534 						(*texts)[ctx->b_ctx.text]->x = x;
   2535 						(*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
   2536 						ctx->b_ctx.text++;
   2537 						x += biggest_line_item_width;
   2538 					}
   2539 					ctx->b_ctx.y -= 8.0 + biggest_font_size;
   2540 				}
   2541 				continue;
   2542 			}
   2543 			for (li = (*se)->lines; *li; li++) {
   2544 				int item_index;
   2545 				int text_above_index;
   2546 				struct CharPosition *pos;
   2547 				struct ChoLineItemAbove **left_aboves = (*li)->text_above;
   2548 				struct ChoLineItem **left_items = (*li)->items;
   2549 
   2550 				while (*left_aboves || *left_items) {
   2551 					bool text_above_exist;
   2552 					char *string;
   2553 					int i;
   2554 					struct ChoStyle *style;
   2555 
   2556 					ctx->b_ctx.consumed_lyrics = 0;
   2557 					ctx->b_ctx.biggest_font_size = 0.0;
   2558 					ctx->b_ctx.prev_added_space = 0.0;
   2559 					if (!calc_space_between_text_above(ctx, left_items, left_aboves, img_objs, &ctx->b_ctx.spaces)) {
   2560 						DEBUG("calc_space_between_text_above failed.");
   2561 						return false;
   2562 					}
   2563 					pos = items_find_position_to_break_line(ctx, left_items, ctx->b_ctx.spaces, img_objs);
   2564 					if (pos->line_item_index == -1) {
   2565 						item_index = 10000;
   2566 						text_above_index = 10000;
   2567 					} else {
   2568 						item_index = pos->line_item_index;
   2569 						text_above_index = text_above_find_index_to_break_line(left_items, left_aboves, pos);
   2570 						if (text_above_index == -2) {
   2571 							DEBUG("text_above_find_index_to_break_line failed.");
   2572 							return false;
   2573 						}
   2574 						if (text_above_index == -1) {
   2575 							text_above_index = 20000;
   2576 						}
   2577 					}
   2578 					for (i = 0; left_aboves[i] && i<text_above_index; i++) {
   2579 						struct SpaceNeeded **sp;
   2580 
   2581 						width = line_width_until_text_above(ctx, left_items, left_aboves[i], img_objs, NULL);
   2582 						if (width == ERROR) {
   2583 							DEBUG("line_width_until_text_above failed.");
   2584 							return false;
   2585 						}
   2586 						ctx->b_ctx.x = MARGIN_HORIZONTAL + width + ctx->b_ctx.prev_added_space;
   2587 						for (sp = ctx->b_ctx.spaces; *sp; sp++) {
   2588 							if ((*sp)->text_above_index == i) {
   2589 								ctx->b_ctx.x += (*sp)->amount;
   2590 								ctx->b_ctx.prev_added_space += (*sp)->amount;
   2591 							}
   2592 						}
   2593 						*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2594 						(*texts)[ctx->b_ctx.text] = pdf_text_new();
   2595 						(*texts)[ctx->b_ctx.text]->x = ctx->b_ctx.x;
   2596 						(*texts)[ctx->b_ctx.text]->y = ctx->b_ctx.y;
   2597 						if (left_aboves[i]->is_chord) {
   2598 							string = cho_chord_name_generate(left_aboves[i]->u.chord);
   2599 							style = cho_style_copy(left_aboves[i]->u.chord->style);
   2600 						} else {
   2601 							string = strdup(left_aboves[i]->u.annot->text);
   2602 							style = cho_style_copy(left_aboves[i]->u.annot->style);
   2603 						}
   2604 						(*texts)[ctx->b_ctx.text]->text = string;
   2605 						(*texts)[ctx->b_ctx.text]->style = style;
   2606 						(*texts)[ctx->b_ctx.text]->width = text_width(ctx, string, style);
   2607 						if ((*texts)[ctx->b_ctx.text]->width == ERROR) {
   2608 							DEBUG("text_width failed.");
   2609 							return false;
   2610 						}
   2611 						if (style->href) {
   2612 							if (!annot_url_link_add(ctx, &ctx->b_ctx, style, (*texts)[ctx->b_ctx.text]->width)) {
   2613 								DEBUG("annot_url_link_add failed.");
   2614 								return false;
   2615 							}
   2616 						}
   2617 						if (style->font->size > ctx->b_ctx.biggest_font_size) {
   2618 							ctx->b_ctx.biggest_font_size = style->font->size;
   2619 						}
   2620 						ctx->b_ctx.text++;
   2621 					}
   2622 					height = images_find_biggest_height(ctx, left_items, pos->line_item_index, img_objs);
   2623 					if (height == ERROR) {
   2624 						DEBUG("images_find_biggest_height failed.");
   2625 						return false;
   2626 					}
   2627 					text_above_exist = i > 0;
   2628 					if (text_above_exist) {
   2629 						left_aboves += i;
   2630 						if (height > 2.0 + ctx->b_ctx.biggest_font_size) {
   2631 							ctx->b_ctx.y -= height;
   2632 						} else {
   2633 							ctx->b_ctx.y -= 2.0 + ctx->b_ctx.biggest_font_size;
   2634 						}
   2635 					} else {
   2636 						if (height > 0.0) {
   2637 							ctx->b_ctx.y -= height;
   2638 						}
   2639 					}
   2640 					if (ctx->b_ctx.y < ctx->b_ctx.margin_bottom) {
   2641 						struct PDFText **tmp = NULL;
   2642 						int tm = 0;
   2643 
   2644 						ctx->b_ctx.y = MEDIABOX_HEIGHT - MARGIN_TOP;
   2645 						if (text_above_exist) {
   2646 							/* INFO: chords/annotations and their corresponding lyrics won't be splitted */
   2647 							int p;
   2648 							double prev_y = (*texts)[ctx->b_ctx.text-1]->y;
   2649 
   2650 							for (p = ctx->b_ctx.text-1; prev_y == (*texts)[p]->y; p--) {
   2651 								(*texts)[p]->y = ctx->b_ctx.y;
   2652 								tmp = erealloc(tmp, (tm+1) * sizeof(struct PDFText *));
   2653 								tmp[tm] = (*texts)[p];
   2654 								tm++;
   2655 								*texts = erealloc(*texts, (--ctx->b_ctx.text) * sizeof(struct PDFText *));
   2656 							}
   2657 						}
   2658 						if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2659 							DEBUG("pdf_page_close_then_add failed.");
   2660 							free(tmp);
   2661 							return false;
   2662 						}
   2663 						texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2664 						imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2665 						diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2666 						if (text_above_exist) {
   2667 							for (int i=0; i<tm; i++) {
   2668 								*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2669 								(*texts)[ctx->b_ctx.text] = tmp[i];
   2670 								ctx->b_ctx.text++;
   2671 							}
   2672 							free(tmp);
   2673 						}
   2674 						if (text_above_exist) {
   2675 							if (height > 2.0 + ctx->b_ctx.biggest_font_size) {
   2676 								ctx->b_ctx.y -= height;
   2677 							} else {
   2678 								ctx->b_ctx.y -= 2.0 + ctx->b_ctx.biggest_font_size;
   2679 							}
   2680 						} else {
   2681 							ctx->b_ctx.y -= height;
   2682 						}
   2683 					}
   2684 					ctx->b_ctx.biggest_font_size = 0.0;
   2685 					ctx->b_ctx.x = MARGIN_HORIZONTAL;
   2686 					i = 0;
   2687 					while (*left_items && i < item_index) {
   2688 						if ((*left_items)->is_text) {
   2689 							if (!pdf_texts_add_lyrics(ctx, *left_items, i)) {
   2690 								DEBUG("pdf_texts_add_lyrics failed.");
   2691 								return false;
   2692 							}
   2693 							texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2694 							imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2695 							diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2696 						} else {
   2697 							*imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
   2698 							(*imgs)[ctx->b_ctx.image] = pdf_image_new();
   2699 							(*imgs)[ctx->b_ctx.image]->name = image_name(ctx, (*left_items)->u.image);
   2700 							if (!(*imgs)[ctx->b_ctx.image]->name) {
   2701 								DEBUG("image_name failed.");
   2702 								return false;
   2703 							}
   2704 							(*imgs)[ctx->b_ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx->b_ctx.image]->name);
   2705 							if (!(*imgs)[ctx->b_ctx.image]->obj) {
   2706 								DEBUG("objs_get_obj failed.");
   2707 								return false;
   2708 							}
   2709 							(*imgs)[ctx->b_ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
   2710 							(*imgs)[ctx->b_ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
   2711 							(*imgs)[ctx->b_ctx.image]->x = ctx->b_ctx.x;
   2712 							(*imgs)[ctx->b_ctx.image]->y = ctx->b_ctx.y;
   2713 							ctx->b_ctx.x += (*imgs)[ctx->b_ctx.image]->width;
   2714 							ctx->b_ctx.image++;
   2715 						}
   2716 						i++;
   2717 						left_items++;
   2718 					}
   2719 					if (pos->line_item_index != -1 && pos->text_index != -1) {
   2720 						if ((*left_items)->is_text) {
   2721 							char *tmp;
   2722 
   2723 							(*left_items)->u.text->text[pos->text_index] = 0;
   2724 							tmp = strdup(&(*left_items)->u.text->text[pos->text_index+1]);
   2725 							if (!pdf_texts_add_lyrics(ctx, *left_items, i)) {
   2726 								DEBUG("pdf_texts_add_lyrics failed.");
   2727 								free(tmp);
   2728 								return false;
   2729 							}
   2730 							free((*left_items)->u.text->text);
   2731 							(*left_items)->u.text->text = tmp;
   2732 							texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2733 							imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2734 							diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2735 						}
   2736 					} else
   2737 					if (pos->line_item_index != -1 && pos->text_index == -1) {
   2738 						if (!(*left_items)->is_text) {
   2739 							*imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
   2740 							(*imgs)[ctx->b_ctx.image] = pdf_image_new();
   2741 							(*imgs)[ctx->b_ctx.image]->name = image_name(ctx, (*left_items)->u.image);
   2742 							if (!(*imgs)[ctx->b_ctx.image]->name) {
   2743 								DEBUG("image_name failed.");
   2744 								return false;
   2745 							}
   2746 							(*imgs)[ctx->b_ctx.image]->obj = objs_get_obj(img_objs, (*imgs)[ctx->b_ctx.image]->name);
   2747 							if (!(*imgs)[ctx->b_ctx.image]->obj) {
   2748 								DEBUG("objs_get_obj failed.");
   2749 								return false;
   2750 							}
   2751 							(*imgs)[ctx->b_ctx.image]->width = image_width((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
   2752 							(*imgs)[ctx->b_ctx.image]->height = image_height((*left_items)->u.image, (*imgs)[ctx->b_ctx.image]->obj);
   2753 							(*imgs)[ctx->b_ctx.image]->x = ctx->b_ctx.x;
   2754 							(*imgs)[ctx->b_ctx.image]->y = ctx->b_ctx.y;
   2755 							ctx->b_ctx.image++;
   2756 						}
   2757 						left_items++;
   2758 					}
   2759 					ctx->b_ctx.y -= 8.0 + ctx->b_ctx.biggest_font_size;
   2760 					if (ctx->b_ctx.y < ctx->b_ctx.margin_bottom) {
   2761 						if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2762 							DEBUG("pdf_page_close_then_add failed.");
   2763 							return false;
   2764 						}
   2765 						texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2766 						imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2767 						diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2768 					}
   2769 					spaces_free(ctx->b_ctx.spaces);
   2770 					ctx->b_ctx.spaces = NULL;
   2771 					free(pos);
   2772 					pos = NULL;
   2773 					text_above_update_positions(left_aboves, ctx->b_ctx.consumed_lyrics);
   2774 				}
   2775 				if ((*li)->btype == BREAK_TYPE_PAGE) {
   2776 					if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2777 						DEBUG("pdf_page_close_then_add failed.");
   2778 						return false;
   2779 					}
   2780 					texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2781 					imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2782 					diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2783 				}
   2784 			}
   2785 			ctx->b_ctx.y -= SECTION_GAP_WIDTH;
   2786 		}
   2787 		if (start_song_on_new_page) {
   2788 			if (!pdf_page_close_then_add(ctx, &ctx->b_ctx, NUMERAL_SYSTEM_WESTERN_ARABIC)) {
   2789 				DEBUG("pdf_page_close_then_add failed.");
   2790 				return false;
   2791 			}
   2792 			texts = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->texts;
   2793 			imgs = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->images;
   2794 			diagrams = &ctx->b_ctx.content->pages[ctx->b_ctx.page]->diagrams;
   2795 		}
   2796 	}
   2797 	*texts = erealloc(*texts, (ctx->b_ctx.text+1) * sizeof(struct PDFText *));
   2798 	(*texts)[ctx->b_ctx.text] = NULL;
   2799 	*imgs = erealloc(*imgs, (ctx->b_ctx.image+1) * sizeof(struct PDFImage *));
   2800 	(*imgs)[ctx->b_ctx.image] = NULL;
   2801 	*diagrams = erealloc(*diagrams, (ctx->b_ctx.diagram+1) * sizeof(struct ChordDiagram *));
   2802 	(*diagrams)[ctx->b_ctx.diagram] = NULL;
   2803 	if (start_song_on_new_page) {
   2804 		pdf_page_free(ctx->b_ctx.content->pages[ctx->b_ctx.page]);
   2805 		ctx->b_ctx.content->pages[ctx->b_ctx.page] = NULL;
   2806 	} else {
   2807 		ctx->b_ctx.page++;
   2808 		ctx->b_ctx.content->pages = erealloc(ctx->b_ctx.content->pages, (ctx->b_ctx.page+1) * sizeof(struct PDFPage *));
   2809 		ctx->b_ctx.content->pages[ctx->b_ctx.page] = NULL;
   2810 	}
   2811 	ctx->b_ctx.content->toc = erealloc(ctx->b_ctx.content->toc, (ctx->b_ctx.toc_entry+1) * sizeof(struct TocEntry *));
   2812 	ctx->b_ctx.content->toc[ctx->b_ctx.toc_entry] = NULL;
   2813 	*out = ctx->b_ctx.content;
   2814 	return true;
   2815 }
   2816 
   2817 static bool
   2818 pdf_toc_render(struct PDFContext *ctx, struct PDFContent *content)
   2819 {
   2820 	struct PDFPage **pages;
   2821 	struct PDFText **texts;
   2822 	pdfio_stream_t *stream;
   2823 	int p;
   2824 
   2825 	pages = content->pages;
   2826 	for (p = 0; pages[p]; p++) {
   2827 		ctx->current_page_index = p;
   2828 		stream = pdf_page_create(ctx, NULL, pages[p]->annots);
   2829 		if (!stream) {
   2830 			DEBUG("pdf_page_create failed.");
   2831 			return false;
   2832 		}
   2833 		for (texts = pages[p]->texts; *texts; texts++) {
   2834 			if (!pdf_text_show(ctx, stream, *texts)) {
   2835 				DEBUG("pdf_text_show failed.");
   2836 				return false;
   2837 			}
   2838 		}
   2839 		if (!pdfioStreamClose(stream)) {
   2840 			DEBUG("pdfioStreamClose failed.");
   2841 			return false;
   2842 		}
   2843 	}
   2844 	return true;
   2845 }
   2846 
   2847 static bool
   2848 pdf_body_render(struct PDFContext *ctx, struct PDFContent *content)
   2849 {
   2850 	int p;
   2851 	struct PDFPage **pages;
   2852 	struct PDFText **texts;
   2853 	struct PDFImage **imgs;
   2854 	pdfio_stream_t *stream;
   2855 
   2856 	pages = content->pages;
   2857 	for (p = 0; pages[p]; p++) {
   2858 		ctx->current_page_index = p;
   2859 		stream = pdf_page_create(ctx, pages[p]->images, pages[p]->annots);
   2860 		if (!stream) {
   2861 			DEBUG("pdf_page_create failed.");
   2862 			return false;
   2863 		}
   2864 		for (texts = pages[p]->texts; *texts; texts++) {
   2865 			if (!pdf_text_show(ctx, stream, *texts)) {
   2866 				DEBUG("pdf_text_show failed.");
   2867 				return false;
   2868 			}
   2869 		}
   2870 		for (imgs = pages[p]->images; *imgs; imgs++) {
   2871 			if (
   2872 				!pdfioContentDrawImage(
   2873 					stream,
   2874 					(*imgs)->name,
   2875 					(*imgs)->x,
   2876 					(*imgs)->y,
   2877 					(*imgs)->width,
   2878 					(*imgs)->height
   2879 				)
   2880 			) {
   2881 				DEBUG("pdfioContentDrawImage failed.");
   2882 				return false;
   2883 			}
   2884 		}
   2885 		if (pages[p]->diagrams) {
   2886 			double x = MARGIN_HORIZONTAL;
   2887 			double y = 50.0;
   2888 			double size = 50.0;
   2889 			double padding = 30.0;
   2890 			struct ChordDiagram **d;
   2891 			/* TODO: Handle line break when too long */
   2892 			for (d = pages[p]->diagrams; *d; d++) {
   2893 				if ((*d)->show) {
   2894 					if (!chord_diagram_draw(ctx, stream, *d, x, y, size)) {
   2895 						DEBUG("chord_diagram_draw failed.");
   2896 						return false;
   2897 					}
   2898 					x += size + padding;
   2899 				}
   2900 			}
   2901 		}
   2902 		if (!pdfioStreamClose(stream)) {
   2903 			DEBUG("pdfioStreamClose failed.");
   2904 			return false;
   2905 		}
   2906 	}
   2907 	return true;
   2908 }
   2909 
   2910 char *
   2911 out_pdf_create(
   2912 	const char *cho_filepath,
   2913 	const char *output_folder_or_file,
   2914 	struct ChoSong **songs,
   2915 	struct Config *config
   2916 )
   2917 {
   2918 	struct Font **needed_fonts = NULL;
   2919 	struct Obj **img_objs = NULL;
   2920 	struct PDFContent *pdf_body = NULL;
   2921 	struct PDFContent *pdf_toc = NULL;
   2922 	struct PDFContext ctx;
   2923 	pdfio_rect_t media_box_a4 = { 0.0, 0.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
   2924 	pdfio_rect_t crop_box = { 0.0, 0.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
   2925 	char *dirpath = NULL;
   2926 	char *pdf_filepath = NULL;
   2927 	char *pdf_dot_filepath = NULL;
   2928 
   2929 	FcInit();
   2930 	ctx.diagram_font_is_base_font = false;
   2931 	ctx.fonts = NULL;
   2932 	ctx.config = config;
   2933 	ctx.current_page_index = 0;
   2934 	ctx.current_font_size = 0.0;
   2935 	memset(&ctx.cho_dirpath, 0, PATH_MAX);
   2936 	memset(&ctx.current_font_name, 0, 200);
   2937 	if (cho_filepath) {
   2938 		dirpath = filepath_dirname(cho_filepath);
   2939 	} else {
   2940 		dirpath = getcwd(NULL, 0);
   2941 	}
   2942 	strcpy((char *)&ctx.cho_dirpath, dirpath);
   2943 	free(dirpath);
   2944 	pdf_filepath = pdf_filepath_create(&ctx, songs, cho_filepath, output_folder_or_file);
   2945 	if (!pdf_filepath) {
   2946 		DEBUG("pdf_filepath_create failed.");
   2947 		goto ERR;
   2948 	}
   2949 	pdf_dot_filepath = filepath_as_dot_file(pdf_filepath);
   2950 	ctx.pdf_file = pdfioFileCreate(pdf_dot_filepath, "2.0", &media_box_a4, &crop_box, NULL, NULL);
   2951 	if (!ctx.pdf_file) {
   2952 		DEBUG("pdfioFileCreateTemporary failed.");
   2953 		goto ERR;
   2954 	}
   2955 	if (!pdf_set_title(&ctx, songs)) {
   2956 		DEBUG("pdf_set_title failed.");
   2957 		goto ERR;
   2958 	}
   2959 	needed_fonts = fonts_get_all(songs, ctx.config);
   2960 	if (!pdf_load_fonts(&ctx, needed_fonts)) {
   2961 		DEBUG("pdf_load_fonts failed.");
   2962 		goto ERR;
   2963 	}
   2964 	cho_fonts_free(needed_fonts);
   2965 	if (!pdf_load_images(&ctx, &img_objs, songs)) {
   2966 		DEBUG("pdf_load_images failed.");
   2967 		goto ERR;
   2968 	}
   2969 	if (!pdf_body_create(&ctx, songs, img_objs, &pdf_body)) {
   2970 		DEBUG("pdf_body_create failed.");
   2971 		goto ERR;
   2972 	}
   2973 	if (ctx.config->output->toc->show) {
   2974 		if (!pdf_toc_create(&ctx, pdf_body, &pdf_toc)) {
   2975 			DEBUG("pdf_toc_create failed.");
   2976 			goto ERR;
   2977 		}
   2978 		if (!pdf_toc_render(&ctx, pdf_toc)) {
   2979 			DEBUG("pdf_toc_render failed.");
   2980 			goto ERR;
   2981 		}
   2982 	}
   2983 	if (!pdf_body_render(&ctx, pdf_body)) {
   2984 		DEBUG("pdf_body_render failed.");
   2985 		goto ERR;
   2986 	}
   2987 	objs_free(img_objs);
   2988 	pdf_content_free(pdf_toc);
   2989 	pdf_content_free(pdf_body);
   2990 	if (!pdfioFileClose(ctx.pdf_file)) {
   2991 		DEBUG("pdfioFileClose failed.");
   2992 	}
   2993 	objs_free(ctx.fonts);
   2994 	if (rename(pdf_dot_filepath, pdf_filepath)) {
   2995 		DEBUG("rename failed.");
   2996 		util_log(
   2997 			NULL,
   2998 			0,
   2999 			LOG_ERR,
   3000 			"Moving temporary created pdf file from '%s' to '%s' failed: %s",
   3001 			pdf_dot_filepath,
   3002 			pdf_filepath,
   3003 			strerror(errno)
   3004 		);
   3005 	}
   3006 	free(pdf_dot_filepath);
   3007 	FcFini();
   3008 	return pdf_filepath;
   3009 	ERR:
   3010 	objs_free(img_objs);
   3011 	pdf_content_free(pdf_toc);
   3012 	pdf_content_free(pdf_body);
   3013 	if (!pdfioFileClose(ctx.pdf_file)) {
   3014 		DEBUG("pdfioFileClose failed.");
   3015 	}
   3016 	objs_free(ctx.fonts);
   3017 	free(pdf_filepath);
   3018 	if (unlink(pdf_dot_filepath)) {
   3019 		DEBUG("unlink failed.");
   3020 	}
   3021 	free(pdf_dot_filepath);
   3022 	FcFini();
   3023 	return NULL;
   3024 }