commit 6073e681b35c177f1ffac50ec67b25411c49c268
parent 93df4ecc41846e02c500324862682557b87edca4
Author: nibo <nibo@relim.de>
Date: Fri, 6 Sep 2024 16:12:48 +0200
'make lib' support
Diffstat:
6 files changed, 337 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile
@@ -13,4 +13,7 @@ fontconfig:
$(CC) -g chordpro.c fontconfig.c -o fontconfig -lfontconfig
parser:
$(CC) ${CFLAGS} -g util.c config.c chordpro.c lorid.c -o parser -ltoml
+lib:
+ $(CC) -fpic -c util.c fontconfig.c config.c chordpro.c out_pdf.c
+ $(CC) -shared ${LDFLAGS} -o liblorid.so *.o
.PHONY: all debug fontconfig parser
diff --git a/lorid.c b/lorid.c
@@ -67,10 +67,26 @@ int main(int argc, char *argv[])
fprintf(stderr, "cho_parse failed.\n");
return 1;
}
- if (!out_pdf_new(argc == optind+1 ? argv[argc-1] : NULL, output ? output : NULL, songs, config)) {
+ int m;
+ for (m = 0; songs[0]->metadata[m]; m++) {
+ printf("'%s' => ", songs[0]->metadata[m]->name);
+ int i;
+ for (i = 0; songs[0]->metadata[m]->value[i] != 0; i++) {
+ printf("[%02X|%c] ", songs[0]->metadata[m]->value[i], songs[0]->metadata[m]->value[i]);
+ }
+ printf("\n");
+ }
+ char *pdf_filename = out_pdf_new(argc == optind+1 ? argv[argc-1] : NULL, output ? output : NULL, songs, config);
+ if (!pdf_filename) {
fprintf(stderr, "out_pdf_new failed.\n");
return 1;
}
+ fprintf(stderr, "INFO: Writing pdf to file: '%s'\n", pdf_filename);
+ free(pdf_filename);
+ /* if (!out_pdf_new(argc == optind+1 ? argv[argc-1] : NULL, output ? output : NULL, songs, config)) {
+ fprintf(stderr, "out_pdf_new failed.\n");
+ return 1;
+ } */
free(output);
cho_songs_free(songs);
config_free(config);
diff --git a/lorid.h b/lorid.h
@@ -0,0 +1,297 @@
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+enum FontFamily {
+ FF_EMPTY = -1,
+ FF_NORMAL,
+ FF_SANS,
+ FF_SERIF,
+ FF_MONOSPACE
+};
+
+enum FontStyle {
+ FS_EMPTY = -1,
+ FS_ROMAN,
+ FS_OBLIQUE,
+ FS_ITALIC
+};
+
+enum FontWeight {
+ FW_EMPTY = -1,
+ FW_REGULAR,
+ FW_BOLD
+};
+
+struct Font {
+ char *name;
+ enum FontFamily family;
+ enum FontStyle style;
+ enum FontWeight weight;
+ double size;
+};
+
+enum LineStyle {
+ LS_EMPTY = -1,
+ LS_SINGLE,
+ LS_DOUBLE,
+ LS_NONE
+};
+
+struct RGBColor {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+};
+
+struct Style {
+ struct Font *font;
+ struct RGBColor *foreground_color;
+ struct RGBColor *background_color;
+ enum LineStyle underline_style;
+ struct RGBColor *underline_color;
+ enum LineStyle overline_style;
+ struct RGBColor *overline_color;
+ bool strikethrough;
+ struct RGBColor *strikethrough_color;
+ bool boxed;
+ struct RGBColor *boxed_color;
+ double rise;
+ char *href;
+};
+
+struct Attr {
+ char *name;
+ char *value;
+};
+
+struct Tag {
+ char *name;
+ struct Style *style;
+ struct Attr **attrs;
+ bool is_closed;
+};
+
+enum AttrValueSyntax {
+ AVS_NO,
+ AVS_QUOTATION_MARK,
+ AVS_APOSTROPHE,
+ AVS_UNQUOTED
+};
+
+enum State {
+ STATE_LYRICS,
+ STATE_DIRECTIVE_NAME,
+ STATE_DIRECTIVE_VALUE,
+ STATE_CHORD,
+ STATE_ANNOTATION,
+ STATE_MARKUP_TAG_BEGIN,
+ STATE_MARKUP_TAG_END,
+ STATE_MARKUP_TAG,
+ STATE_MARKUP_ATTR_NAME,
+ STATE_MARKUP_ATTR_VALUE,
+ STATE_COMMENT
+};
+
+/* Similar to SectionType but different enough for a separate type */
+enum SongFragmentType {
+ SF_EMPTY = -1,
+ SF_CHORD,
+ SF_ANNOT,
+ SF_CHORUS,
+ SF_FOOTER,
+ SF_GRID,
+ SF_TAB,
+ SF_TOC,
+ SF_TEXT,
+ SF_TITLE,
+ SF_LABEL
+};
+
+enum StylePropertyType {
+ SPT_EMPTY = -1,
+ SPT_FONT,
+ SPT_SIZE,
+ SPT_COLOR
+};
+
+union StylePropertyValue {
+ char *font_name;
+ double font_size;
+ struct RGBColor *foreground_color;
+};
+
+struct StyleProperty {
+ enum SongFragmentType ftype;
+ enum StylePropertyType type;
+ union StylePropertyValue u;
+};
+
+enum DirectiveType {
+ DT_EMPTY = -1,
+ DT_ENVIRONMENT,
+ DT_METADATA,
+ DT_FORMATTING,
+ DT_PREAMBLE,
+ DT_FONT,
+ DT_OUTPUT,
+ DT_CUSTOM
+};
+
+enum SectionType {
+ ST_EMPTY = -1,
+ ST_NEWSONG,
+ ST_CHORUS,
+ ST_VERSE,
+ ST_BRIDGE,
+ ST_TAB,
+ ST_GRID,
+ ST_CUSTOM
+};
+
+enum Position {
+ POS_EMPTY = -1,
+ POS_START,
+ POS_END
+};
+
+enum ChordQualifier {
+ CQ_EMPTY = -1,
+ CQ_MIN,
+ CQ_MAJ,
+ CQ_AUG,
+ CQ_DIM
+};
+
+enum BreakType {
+ BT_EMPTY = -1,
+ BT_LINE,
+ BT_PAGE,
+ BT_COLUMN
+};
+
+struct ChoDirective {
+ enum DirectiveType dtype;
+ enum SectionType stype;
+ enum Position position;
+ enum StylePropertyType sprop;
+ enum SongFragmentType ftype;
+ enum BreakType btype;
+ struct Style *style;
+};
+
+struct ChoMetadata {
+ char *name;
+ char *value;
+ struct Style *style;
+};
+
+struct ChoChord {
+ struct Style *style;
+ bool is_canonical;
+ char *name;
+ char *root;
+ enum ChordQualifier qual;
+ char *ext;
+ char *bass;
+};
+
+struct ChoAnnotation {
+ struct Style *style;
+ char *text;
+};
+
+struct ChoLineItem {
+ struct Style *style;
+ char *text;
+};
+
+struct ChoLineItemAbove {
+ int position;
+ bool is_chord;
+ union {
+ struct ChoChord *chord;
+ struct ChoAnnotation *annot;
+ } u;
+};
+
+struct ChoLine {
+ struct ChoLineItemAbove **text_above;
+ struct ChoLineItem **lyrics;
+ enum BreakType btype;
+};
+
+struct ChoLabel {
+ char *name;
+ struct Style *style;
+};
+
+struct ChoSection {
+ enum SectionType type;
+ struct ChoLabel *label;
+ struct ChoLine **lines;
+};
+
+struct ChoSong {
+ struct ChoMetadata **metadata;
+ struct ChoSection **sections;
+};
+
+struct PrintableItem {
+ char *name;
+ struct Style *style;
+};
+
+enum NamingSystem {
+ NS_COMMON,
+ NS_GERMAN,
+ NS_SCANDINAVIAN,
+ NS_LATIN,
+ NS_ROMAN,
+ NS_NASHVILLE,
+ NS_CUSTOM
+};
+
+enum ParseMode {
+ PM_STRICT,
+ PM_RELAXED
+};
+
+struct Note {
+ char *note;
+ char *sharp;
+ char *flat;
+};
+
+struct ConfigChords {
+ enum NamingSystem system;
+ enum ParseMode mode;
+ // struct Note **notes;
+};
+
+/* struct Config {
+ struct PrintableItem **printable_items;
+ struct ConfigChords *chords;
+}; */
+
+struct ConfigParser {
+ struct ConfigChords *chords;
+ struct Note **notes;
+};
+
+struct ConfigOutput {
+ enum NamingSystem system;
+ struct PrintableItem **printable_items;
+ struct Note **notes;
+};
+
+struct Config {
+ struct ConfigOutput *output;
+ struct ConfigParser *parser;
+};
+
+extern struct ChoSong **cho_songs_parse(FILE *fp, struct Config *config);
+extern void cho_songs_free(struct ChoSong **song);
+extern char *out_pdf_new(const char *cho_filename, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config);
+extern struct Config *config_load(const char *filepath);
+extern void config_free(struct Config *config);
diff --git a/out_pdf.c b/out_pdf.c
@@ -361,6 +361,13 @@ static double text_width(struct TextLineItem *item)
return -1.0;
}
free(name);
+ /* int i = 0;
+ while (item->text[i] != 0) {
+ printf("%02X ", item->text[i]);
+ i++;
+ }
+ printf("\n"); */
+ // printf("size: %.1f\n", item->style->font->size);
return pdfioContentTextMeasure(font_obj, item->text, item->style->font->size);
}
@@ -630,6 +637,7 @@ static struct Text **text_create(struct ChoSong **songs, struct Config *config)
text[t]->lines[tl]->items = malloc(2 * sizeof(struct TextLineItem *));
text[t]->lines[tl]->items[0] = malloc(sizeof(struct TextLineItem));
text[t]->lines[tl]->items[0]->text = strdup(songs[so]->metadata[m]->value);
+ printf("strdup text: %s\n", text[t]->lines[tl]->items[0]->text);
text[t]->lines[tl]->items[0]->style = cho_style_duplicate(songs[so]->metadata[m]->style);
width = text_width(text[t]->lines[tl]->items[0]);
if (width == EMPTY) {
@@ -1021,22 +1029,20 @@ static pdfio_stream_t *out_pdf_page_create(pdfio_file_t *pdf, pdfio_array_t *ann
return page_stream;
}
-bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config)
+char *out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config)
{
memset(&g_current_font_name, 0, sizeof(g_current_font_name));
char *pdf_filename = out_pdf_filename_create(songs, cho_filepath, output_folder_or_file);
if (!pdf_filename) {
fprintf(stderr, "out_pdf_filename_create failed.\n");
- return false;
+ return NULL;
}
pdfio_rect_t media_box_a4 = { 0.0, 0.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
pdfio_rect_t crop_box = { 36.0, 36.0, MEDIABOX_WIDTH, MEDIABOX_HEIGHT };
- fprintf(stderr, "INFO: Writing pdf to file: '%s'\n", pdf_filename);
pdfio_file_t *pdf = pdfioFileCreate(pdf_filename, "2.0", &media_box_a4, &crop_box, NULL, NULL);
- free(pdf_filename);
if (!out_pdf_set_title(pdf, songs)) {
fprintf(stderr, "out_pdf_set_title failed.\n");
- return false;
+ return NULL;
}
struct Font **needed_fonts = out_pdf_font_get_all(songs, config);
struct Fnt *fnt;
@@ -1061,7 +1067,7 @@ bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, st
} else {
fprintf(stderr, "ERR: Didn't find font file for following font:\n");
cho_font_print(needed_fonts[f]);
- return false;
+ return NULL;
}
}
f++;
@@ -1070,12 +1076,12 @@ bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, st
struct Text **text = text_create(songs, config);
if (!text) {
fprintf(stderr, "text_create failed.\n");
- return false;
+ return NULL;
}
pdfio_array_t *annots = pdfioArrayCreate(pdf);
if (!annots_create(pdf, annots, text)) {
fprintf(stderr, "annotations_create failed.\n");
- return false;
+ return NULL;
}
pdfio_stream_t *page_stream;
int p = 0;
@@ -1092,7 +1098,7 @@ bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, st
if (text[t]->lines[tl]->btype == BT_PAGE) {
if (!pdfioStreamClose(page_stream)) {
fprintf(stderr, "pdfioStreamClose failed.\n");
- return false;
+ return NULL;
}
p++;
page_stream = out_pdf_page_create(pdf, annots, p);
@@ -1104,13 +1110,14 @@ bool out_pdf_new(const char *cho_filepath, const char *output_folder_or_file, st
}
if (!pdfioStreamClose(page_stream)) {
fprintf(stderr, "pdfioStreamClose failed.\n");
- return false;
+ return NULL;
}
if (!pdfioFileClose(pdf)) {
fprintf(stderr, "pdfioFileClose failed.\n");
- return false;
+ return NULL;
}
text_free(text);
out_pdf_fnts_free(g_fonts);
- return true;
+ g_fonts = NULL;
+ return pdf_filename;
}
diff --git a/out_pdf.h b/out_pdf.h
@@ -55,4 +55,4 @@ enum LineLocation {
LL_UNDER
};
-bool out_pdf_new(const char *cho_filename, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config);
+char *out_pdf_new(const char *cho_filename, const char *output_folder_or_file, struct ChoSong **songs, struct Config *config);
diff --git a/out_pdf.o b/out_pdf.o
Binary files differ.