commit b8ffeb167f0bb1a4efec711b3eaea904f73264de
parent 62e44e7c89b2c449ab8ce7d4b359d11a574fd83a
Author: nibo <nibo@relim.de>
Date: Sun, 7 Jul 2024 17:40:01 +0200
A lot
Diffstat:
| M | Makefile | | | 7 | +++++-- |
| M | chordpro.c | | | 86 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------- |
| M | chordpro.h | | | 21 | ++++++++++++++++++--- |
| M | config.c | | | 300 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
| M | config.h | | | 24 | +++++++++--------------- |
| A | fontconfig.c | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | fontconfig.h | | | 8 | ++++++++ |
| M | lorid.c | | | 9 | ++++++--- |
| M | out_pdf.c | | | 313 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
| M | out_pdf.h | | | 8 | +++++--- |
| M | todo | | | 1 | + |
11 files changed, 607 insertions(+), 268 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,4 +1,7 @@
all:
- $(CC) -Wall -Wextra -O2 config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml
+ $(CC) -Wall -Wextra -O2 fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig
debug:
- $(CC) -g -Wall -Wextra config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml
+ $(CC) -g -Wall -Wextra fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -I/usr/include/freetype2 -lpdfio -ltoml -lfontconfig
+fontconfig:
+ $(CC) -g chordpro.c fontconfig.c -o fontconfig -lfontconfig
+.PHONY: all debug fontconfig
diff --git a/chordpro.c b/chordpro.c
@@ -142,8 +142,8 @@ const char *the_font_style(enum FontStyle style)
switch (style) {
case FS_EMPTY:
return "FS_EMPTY";
- case FS_REGULAR:
- return "FS_REGULAR";
+ case FS_ROMAN:
+ return "FS_ROMAN";
case FS_OBLIQUE:
return "FS_OBLIQUE";
case FS_ITALIC:
@@ -157,8 +157,8 @@ const char *the_font_weight(enum FontWeight weight)
switch (weight) {
case FW_EMPTY:
return "FW_EMPTY";
- case FW_NORMAL:
- return "FW_NORMAL";
+ case FW_REGULAR:
+ return "FW_REGULAR";
case FW_BOLD:
return "FW_BOLD";
}
@@ -349,13 +349,13 @@ struct Font *cho_font_new(void)
struct Font *font = malloc(sizeof(struct Font));
font->name = NULL;
font->family = FF_NORMAL;
- font->style = FS_REGULAR;
- font->weight = FW_NORMAL;
+ font->style = FS_ROMAN;
+ font->weight = FW_REGULAR;
font->size = DEFAULT_FONT_SIZE;
return font;
}
-static struct Font *cho_font_duplicate(struct Font *font)
+struct Font *cho_font_duplicate(struct Font *font)
{
struct Font *copy = malloc(sizeof(struct Font));
if (font->name)
@@ -399,6 +399,52 @@ void cho_fonts_free(struct Font **fonts)
free(fonts);
}
+char *cho_font_name_sanitize(const char *name)
+{
+ char *sanitized = NULL;
+ int i = 0;
+ int s = 0;
+ char c;
+ for (; name[i] != 0; i++) {
+ if (name[i] == ' ')
+ continue;
+ c = (char)tolower(name[i]);
+ sanitized = realloc(sanitized, (s+1) * sizeof(char));
+ sanitized[s] = c;
+ s++;
+ }
+ sanitized = realloc(sanitized, (s+1) * sizeof(char));
+ sanitized[s] = 0;
+ return sanitized;
+}
+
+enum FontFamily cho_font_family_parse(const char *str)
+{
+ if (strcasecmp(str, "sans") == 0) {
+ return FF_SANS;
+ } else if (strcasecmp(str, "serif") == 0) {
+ return FF_SERIF;
+ } else if (strcasecmp(str, "monospace") == 0) {
+ return FF_MONOSPACE;
+ } else {
+ return FF_EMPTY;
+ }
+}
+
+const char *cho_font_family_to_string(enum FontFamily font_family)
+{
+ switch (font_family) {
+ case FF_SANS:
+ return "sans";
+ case FF_SERIF:
+ return "serif";
+ case FF_MONOSPACE:
+ return "monospace";
+ default:
+ return "normal";
+ }
+}
+
enum FontStyle cho_font_style_parse(const char *str)
{
if (strcasecmp(str, "italic") == 0) {
@@ -406,9 +452,7 @@ enum FontStyle cho_font_style_parse(const char *str)
} else if (strcasecmp(str, "oblique") == 0) {
return FS_OBLIQUE;
} else if (strcasecmp(str, "normal") == 0) {
- return FS_REGULAR;
- } else if (strcasecmp(str, "regular") == 0) {
- return FS_REGULAR;
+ return FS_ROMAN;
} else {
return FS_EMPTY;
}
@@ -420,7 +464,7 @@ const char *cho_font_style_to_string(enum FontStyle style)
return "italic";
if (style == FS_OBLIQUE)
return "oblique";
- return "regular";
+ return "normal";
}
enum FontWeight cho_font_weight_parse(const char *str)
@@ -428,9 +472,9 @@ enum FontWeight cho_font_weight_parse(const char *str)
if (strcasecmp(str, "bold") == 0) {
return FW_BOLD;
} else if (strcasecmp(str, "regular") == 0) {
- return FW_NORMAL;
+ return FW_REGULAR;
} else if (strcasecmp(str, "normal") == 0) {
- return FW_NORMAL;
+ return FW_REGULAR;
} else {
return FW_EMPTY;
}
@@ -443,12 +487,12 @@ const char *cho_font_weight_to_string(enum FontWeight weight)
return "regular";
}
-int cho_font_weight_to_int(enum FontWeight weight)
+/* int cho_font_weight_to_int(enum FontWeight weight)
{
if (weight == FW_BOLD)
return 200;
return 80;
-}
+} */
struct Style *cho_style_new(void)
{
@@ -549,21 +593,21 @@ struct Font *cho_style_font_desc_parse(const char *str)
if (stop_at == -1)
stop_at = w;
} else if (strcasecmp(words[w], "regular") == 0) {
- font->weight = FW_NORMAL;
+ font->weight = FW_REGULAR;
if (stop_at == -1)
stop_at = w;
} else if (strcasecmp(words[w], "normal") == 0) {
- font->style = FS_REGULAR;
+ font->style = FS_ROMAN;
if (stop_at == -1)
stop_at = w;
- } else if (strcasecmp(words[w], "sans") == 0) {
+ /* } else if (strcasecmp(words[w], "sans") == 0) {
font->family = FF_SANS;
if (stop_at == -1)
stop_at = w;
} else if (strcasecmp(words[w], "serif") == 0) {
font->family = FF_SERIF;
if (stop_at == -1)
- stop_at = w;
+ stop_at = w; */
} else if (strcasecmp(words[w], "monospace") == 0) {
font->family = FF_MONOSPACE;
if (stop_at == -1)
@@ -691,7 +735,7 @@ struct Style *cho_style_get(const char *tag_name, struct Attr **attrs, struct St
}
} else if (strcmp(attrs[a]->name, "style") == 0) {
if (strcmp(attrs[a]->value, "normal") == 0) {
- style->font->style = FS_REGULAR;
+ style->font->style = FS_ROMAN;
} else if (strcmp(attrs[a]->value, "oblique") == 0) {
style->font->style = FS_OBLIQUE;
} else if (strcmp(attrs[a]->value, "italic") == 0) {
@@ -701,7 +745,7 @@ struct Style *cho_style_get(const char *tag_name, struct Attr **attrs, struct St
}
} else if (strcmp(attrs[a]->name, "weight") == 0) {
if (strcmp(attrs[a]->value, "normal") == 0) {
- style->font->weight = FW_NORMAL;
+ style->font->weight = FW_REGULAR;
} else if (strcmp(attrs[a]->value, "bold") == 0) {
style->font->weight = FW_BOLD;
} else {
diff --git a/chordpro.h b/chordpro.h
@@ -1,5 +1,8 @@
/* ChordPro markup language <https://chordpro.org/chordpro/chordpro_markup> */
+#ifndef _CHORDPRO_H_
+#define _CHORDPRO_H_
+
#define RISE_MAX
#define DEFAULT_FONT_SIZE 14.0
// Based on https://stackoverflow.com/a/417184
@@ -15,14 +18,14 @@ enum FontFamily {
enum FontStyle {
FS_EMPTY = -1,
- FS_REGULAR,
+ FS_ROMAN,
FS_OBLIQUE,
FS_ITALIC
};
enum FontWeight {
FW_EMPTY = -1,
- FW_NORMAL,
+ FW_REGULAR,
FW_BOLD
};
@@ -33,6 +36,7 @@ struct Font {
enum FontWeight weight;
double size;
};
+// "Inter-monospace-regular-regular-12.0"
enum LineStyle {
LS_SINGLE,
@@ -162,14 +166,23 @@ void cho_songs_free(struct ChoSong **song);
int cho_line_item_count(struct ChoLineItem **items);
int cho_chord_count(struct ChoChord **chords);
struct Font *cho_style_font_desc_parse(const char *str);
+
struct Font *cho_font_new(void);
void cho_font_free(struct Font *font);
+struct Font *cho_font_duplicate(struct Font *font);
void cho_fonts_free(struct Font **fonts);
+
+char *cho_font_name_sanitize(const char *name);
+
+enum FontFamily cho_font_family_parse(const char *str);
+const char *cho_font_family_to_string(enum FontFamily font_family);
+
enum FontStyle cho_font_style_parse(const char *str);
const char *cho_font_style_to_string(enum FontStyle style);
+
enum FontWeight cho_font_weight_parse(const char *str);
const char *cho_font_weight_to_string(enum FontWeight weight);
-int cho_font_weight_to_int(enum FontWeight weight);
+// int cho_font_weight_to_int(enum FontWeight weight);
/* Debugging */
void cho_font_print(struct Font *font);
@@ -182,3 +195,5 @@ const char *the_font_style(enum FontStyle style);
const char *the_font_weight(enum FontWeight weight);
const char *the_rgb_color(struct RGBColor *color);
const char *the_line_style(enum LineStyle style);
+
+#endif /* _CHORDPRO_H_ */
diff --git a/config.c b/config.c
@@ -8,54 +8,65 @@
struct Config *config_load_default(void)
{
struct Config *config = malloc(sizeof(struct Config));
- config->title = malloc(sizeof(struct ConfigSection));
- config->title->font_name = strdup("Inter");
- config->title->font_style = FS_REGULAR;
- config->title->font_weight = FW_BOLD;
- config->title->font_size = 18.0;
- config->text = malloc(sizeof(struct ConfigSection));
- config->text->font_name = strdup("Inter");
- config->text->font_style = FS_REGULAR;
- config->text->font_weight = FW_NORMAL;
- config->text->font_size = 14.0;
- config->chord = malloc(sizeof(struct ConfigSection));
- config->chord->font_name = strdup("Inter");
- config->chord->font_style = FS_REGULAR;
- config->chord->font_weight = FW_BOLD;
- config->chord->font_size = 14.0;
- config->comment = malloc(sizeof(struct ConfigSection));
- config->comment->font_name = strdup("Inter");
- config->comment->font_style = FS_REGULAR;
- config->comment->font_weight = FW_NORMAL;
- config->comment->font_size = 14.0;
- config->comment_italic = malloc(sizeof(struct ConfigSection));
- config->comment_italic->font_name = strdup("Inter");
- config->comment_italic->font_style = FS_ITALIC;
- config->comment_italic->font_weight = FW_BOLD;
- config->comment_italic->font_size = 14.0;
- config->comment_box = malloc(sizeof(struct ConfigSection));
- config->comment_box->font_name = strdup("Inter");
- config->comment_box->font_style = FS_REGULAR;
- config->comment_box->font_weight = FW_NORMAL;
- config->comment_box->font_size = 14.0;
- config->tab = malloc(sizeof(struct ConfigSection));
- config->tab->font_name = strdup("Inter");
- config->tab->font_style = FS_REGULAR;
- config->tab->font_weight = FW_NORMAL;
- config->tab->font_size = 14.0;
- config->grid = malloc(sizeof(struct ConfigSection));
- config->grid->font_name = strdup("Inter");
- config->grid->font_style = FS_REGULAR;
- config->grid->font_weight = FW_BOLD;
- config->grid->font_size = 14.0;
+ config->title_font = malloc(sizeof(struct Font));
+ config->title_font->family = FF_NORMAL;
+ config->title_font->name = strdup("Inter");
+ config->title_font->style = FS_ROMAN;
+ config->title_font->weight = FW_BOLD;
+ config->title_font->size = 18.0;
+ config->text_font = malloc(sizeof(struct Font));
+ config->text_font->name = strdup("Inter");
+ config->text_font->family = FF_NORMAL;
+ config->text_font->style = FS_ROMAN;
+ config->text_font->weight = FW_REGULAR;
+ config->text_font->size = 14.0;
+ config->chord_font = malloc(sizeof(struct Font));
+ config->chord_font->name = strdup("Inter");
+ config->chord_font->family = FF_NORMAL;
+ config->chord_font->style = FS_ROMAN;
+ config->chord_font->weight = FW_BOLD;
+ config->chord_font->size = 14.0;
+ config->comment_font = malloc(sizeof(struct Font));
+ config->comment_font->name = strdup("Inter");
+ config->comment_font->family = FF_NORMAL;
+ config->comment_font->style = FS_ROMAN;
+ config->comment_font->weight = FW_REGULAR;
+ config->comment_font->size = 14.0;
+ config->comment_italic_font = malloc(sizeof(struct Font));
+ config->comment_italic_font->name = strdup("Inter");
+ config->comment_italic_font->family = FF_NORMAL;
+ config->comment_italic_font->style = FS_ITALIC;
+ config->comment_italic_font->weight = FW_BOLD;
+ config->comment_italic_font->size = 14.0;
+ config->comment_box_font = malloc(sizeof(struct Font));
+ config->comment_box_font->name = strdup("Inter");
+ config->comment_box_font->family = FF_NORMAL;
+ config->comment_box_font->style = FS_ROMAN;
+ config->comment_box_font->weight = FW_REGULAR;
+ config->comment_box_font->size = 14.0;
+ config->tab_font = malloc(sizeof(struct Font));
+ config->tab_font->name = strdup("Inter");
+ config->tab_font->family = FF_NORMAL;
+ config->tab_font->style = FS_ROMAN;
+ config->tab_font->weight = FW_REGULAR;
+ config->tab_font->size = 14.0;
+ config->grid_font = malloc(sizeof(struct Font));
+ config->grid_font->name = strdup("Inter");
+ config->grid_font->family = FF_NORMAL;
+ config->grid_font->style = FS_ROMAN;
+ config->grid_font->weight = FW_BOLD;
+ config->grid_font->size = 14.0;
return config;
}
struct Config *config_load(const char *filepath)
{
struct Config *config = config_load_default();
+ char *home = getenv("HOME");
+ char path[26+strlen(home)+1];
if (filepath == NULL) {
- filepath = "~/.config/lorid/config.toml";
+ sprintf(path, "%s/.config/lorid/config.toml", home);
+ filepath = path;
}
FILE *fp = fopen(filepath, "r");
if (fp == NULL) {
@@ -66,7 +77,8 @@ struct Config *config_load(const char *filepath)
toml_table_t *table = toml_parse_file(fp, (char *)&errbuf, sizeof(errbuf));
toml_table_t *fonts = toml_table_table(table, "fonts");
toml_table_t *section;
- toml_value_t name, style, weight, size;
+ toml_value_t name, family, style, weight, size;
+ enum FontFamily font_family;
enum FontStyle font_style;
enum FontWeight font_weight;
int unused;
@@ -75,21 +87,32 @@ struct Config *config_load(const char *filepath)
key_name = toml_table_key(fonts, i, &unused);
section = toml_table_table(fonts, key_name);
name = toml_table_string(section, "name");
+ family = toml_table_string(section, "family");
style = toml_table_string(section, "style");
weight = toml_table_string(section, "weight");
size = toml_table_int(section, "size");
if (strcmp(key_name, "title") == 0) {
if (name.ok) {
- free(config->title->font_name);
- config->title->font_name = name.u.s;
+ free(config->title_font->name);
+ config->title_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config title section font family value.\n");
+ return NULL;
+ } else {
+ config->title_font->family = font_family;
+ }
}
if (style.ok) {
+ printf("style here\n");
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
fprintf(stderr, "INFO: Invalid config title section font style value.\n");
return NULL;
} else {
- config->title->font_style = font_style;
+ config->title_font->style = font_style;
}
free(style.u.s);
}
@@ -99,206 +122,269 @@ struct Config *config_load(const char *filepath)
fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
return NULL;
} else {
- config->title->font_weight = font_weight;
+ config->title_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok)
- config->title->font_size = size.u.i;
+ config->title_font->size = size.u.i;
} else if (strcmp(key_name, "text") == 0) {
if (name.ok) {
- free(config->text->font_name);
- config->text->font_name = name.u.s;
+ free(config->text_font->name);
+ config->text_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config text section font family value.\n");
+ return NULL;
+ } else {
+ config->text_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config text section font style value.\n");
return NULL;
} else {
- config->text->font_style = font_style;
+ config->text_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config text section font weight value.\n");
return NULL;
} else {
- config->text->font_weight = font_weight;
+ config->text_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok)
- config->text->font_size = size.u.i;
+ config->text_font->size = size.u.i;
} else if (strcmp(key_name, "chord") == 0) {
if (name.ok) {
- free(config->chord->font_name);
- config->chord->font_name = name.u.s;
+ free(config->chord_font->name);
+ config->chord_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config chord section font family value.\n");
+ return NULL;
+ } else {
+ config->chord_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config chord section font style value.\n");
return NULL;
} else {
- config->chord->font_style = font_style;
+ config->chord_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config chord section font weight value.\n");
return NULL;
} else {
- config->chord->font_weight = font_weight;
+ config->chord_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->chord->font_size = size.u.i;
+ config->chord_font->size = size.u.i;
}
} else if (strcmp(key_name, "comment") == 0) {
if (name.ok) {
- free(config->comment->font_name);
- config->comment->font_name = name.u.s;
+ free(config->comment_font->name);
+ config->comment_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config comment section font family value.\n");
+ return NULL;
+ } else {
+ config->comment_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config comment section font style value.\n");
return NULL;
} else {
- config->comment->font_style = font_style;
+ config->comment_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config comment section font weight value.\n");
return NULL;
} else {
- config->comment->font_weight = font_weight;
+ config->comment_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->comment->font_size = size.u.i;
+ config->comment_font->size = size.u.i;
}
} else if (strcmp(key_name, "comment_italic") == 0) {
if (name.ok) {
- free(config->comment_italic->font_name);
- config->comment_italic->font_name = name.u.s;
+ free(config->comment_italic_font->name);
+ config->comment_italic_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config comment_italic section font family value.\n");
+ return NULL;
+ } else {
+ config->comment_italic_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config comment_italic section font style value.\n");
return NULL;
} else {
- config->comment_italic->font_style = font_style;
+ config->comment_italic_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config comment_italic section font weight value.\n");
return NULL;
} else {
- config->comment_italic->font_weight = font_weight;
+ config->comment_italic_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->comment_italic->font_size = size.u.i;
+ config->comment_italic_font->size = size.u.i;
}
} else if (strcmp(key_name, "comment_box") == 0) {
if (name.ok) {
- free(config->comment_box->font_name);
- config->comment_box->font_name = name.u.s;
+ free(config->comment_box_font->name);
+ config->comment_box_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config comment_box section font family value.\n");
+ return NULL;
+ } else {
+ config->comment_box_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config comment_box section font style value.\n");
return NULL;
} else {
- config->comment_box->font_style = font_style;
+ config->comment_box_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config comment_box section font weight value.\n");
return NULL;
} else {
- config->comment_box->font_weight = font_weight;
+ config->comment_box_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->comment_box->font_size = size.u.i;
+ config->comment_box_font->size = size.u.i;
}
} else if (strcmp(key_name, "tab") == 0) {
if (name.ok) {
- free(config->tab->font_name);
- config->tab->font_name = name.u.s;
+ free(config->tab_font->name);
+ config->tab_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config tab section font family value.\n");
+ return NULL;
+ } else {
+ config->tab_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config tab section font style value.\n");
return NULL;
} else {
- config->tab->font_style = font_style;
+ config->tab_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config tab section font weight value.\n");
return NULL;
} else {
- config->tab->font_weight = font_weight;
+ config->tab_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->tab->font_size = size.u.i;
+ config->tab_font->size = size.u.i;
}
} else if (strcmp(key_name, "grid") == 0) {
if (name.ok) {
- free(config->grid->font_name);
- config->grid->font_name = name.u.s;
+ free(config->grid_font->name);
+ config->grid_font->name = name.u.s;
+ }
+ if (family.ok) {
+ font_family = cho_font_family_parse(family.u.s);
+ if (font_family == FF_EMPTY) {
+ fprintf(stderr, "INFO: Invalid config grid section font family value.\n");
+ return NULL;
+ } else {
+ config->grid_font->family = font_family;
+ }
}
if (style.ok) {
font_style = cho_font_style_parse(style.u.s);
if (font_style == FS_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font style value.\n");
+ fprintf(stderr, "INFO: Invalid config grid section font style value.\n");
return NULL;
} else {
- config->grid->font_style = font_style;
+ config->grid_font->style = font_style;
}
free(style.u.s);
}
if (weight.ok) {
font_weight = cho_font_weight_parse(weight.u.s);
if (font_weight == FW_EMPTY) {
- fprintf(stderr, "INFO: Invalid config title section font weight value.\n");
+ fprintf(stderr, "INFO: Invalid config grid section font weight value.\n");
return NULL;
} else {
- config->grid->font_weight = font_weight;
+ config->grid_font->weight = font_weight;
}
free(weight.u.s);
}
if (size.ok) {
- config->grid->font_size = size.u.i;
+ config->grid_font->size = size.u.i;
}
} else {
fprintf(stderr, "INFO: Ignoring [fonts.%s] section in config file.\n", key_name);
@@ -315,21 +401,15 @@ struct Config *config_load(const char *filepath)
return config;
}
-static void config_section_free(struct ConfigSection *section)
-{
- free(section->font_name);
- free(section);
-}
-
void config_free(struct Config *config)
{
- config_section_free(config->title);
- config_section_free(config->text);
- config_section_free(config->chord);
- config_section_free(config->comment);
- config_section_free(config->comment_italic);
- config_section_free(config->comment_box);
- config_section_free(config->tab);
- config_section_free(config->grid);
+ cho_font_free(config->title_font);
+ cho_font_free(config->text_font);
+ cho_font_free(config->chord_font);
+ cho_font_free(config->comment_font);
+ cho_font_free(config->comment_italic_font);
+ cho_font_free(config->comment_box_font);
+ cho_font_free(config->tab_font);
+ cho_font_free(config->grid_font);
free(config);
}
diff --git a/config.h b/config.h
@@ -1,19 +1,13 @@
-struct ConfigSection {
- char *font_name;
- enum FontStyle font_style;
- enum FontWeight font_weight;
- float font_size;
-};
-
struct Config {
- struct ConfigSection *title;
- struct ConfigSection *text;
- struct ConfigSection *chord;
- struct ConfigSection *comment;
- struct ConfigSection *comment_italic;
- struct ConfigSection *comment_box;
- struct ConfigSection *tab;
- struct ConfigSection *grid;
+ struct Font *title_font;
+ struct Font *text_font;
+ struct Font *chord_font;
+ struct Font *comment_font;
+ struct Font *comment_italic_font;
+ struct Font *comment_box_font;
+ struct Font *tab_font;
+ struct Font *grid_font;
+ // TODO: section_name_font?
};
struct Config *config_load(const char *filepath);
diff --git a/fontconfig.c b/fontconfig.c
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+// #include <ft2build.h>
+// #include <freetype/freetype.h>
+#include <fontconfig/fontconfig.h>
+#include "fontconfig.h"
+
+bool file_extension_is_ttc(const char *filepath)
+{
+ int mark = -1;
+ int i = 0;
+ while (filepath[i] != 0) {
+ if (filepath[i] == '.') {
+ mark = i;
+ }
+ i++;
+ }
+ if (strcmp(&filepath[mark+1], "ttc") == 0)
+ return true;
+ return false;
+}
+
+char *fontconfig_fontpath_find(struct Font *font, enum FontType font_type)
+{
+ char *filepath = NULL;
+ FcObjectSet *obj = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT, FC_FONTFORMAT, FC_FONT_WRAPPER, FC_FILE, NULL);
+ FcPattern *pattern = FcPatternCreate();
+ FcValue family = { .type = FcTypeString, .u.s = (FcChar8 *)font->name };
+ FcPatternAdd(pattern, FC_FAMILY, family, FcFalse);
+ FcValue font_wrapper = { .type = FcTypeString, .u.s = (FcChar8 *)"SFNT" };
+ FcPatternAdd(pattern, FC_FONT_WRAPPER, font_wrapper, FcFalse);
+ /* TODO: Also handle FF_NORMAL, FF_SANS and FF_SERIF, but how? */
+ if (font->family == FF_MONOSPACE) {
+ FcValue spacing = { .type = FcTypeInteger, .u.i = FC_MONO };
+ FcPatternAdd(pattern, FC_SPACING, spacing, FcFalse);
+ }
+ FcValue type;
+ type.type = FcTypeString;
+ if (font_type == FT_OTF)
+ type.u.s = (FcChar8 *)"CFF";
+ else
+ type.u.s = (FcChar8 *)"TrueType";
+ FcPatternAdd(pattern, FC_FONTFORMAT, type, FcFalse);
+ FcValue style;
+ style.type = FcTypeInteger;
+ switch (font->style) {
+ case FS_ROMAN:
+ style.u.i = FC_SLANT_ROMAN;
+ break;
+ case FS_OBLIQUE:
+ style.u.i = FC_SLANT_OBLIQUE;
+ break;
+ case FS_ITALIC:
+ style.u.i = FC_SLANT_ITALIC;
+ break;
+ }
+ FcPatternAdd(pattern, FC_SLANT, style, FcFalse);
+ FcValue weight;
+ weight.type = FcTypeInteger;
+ switch (font->weight) {
+ case FW_REGULAR:
+ weight.u.i = FC_WEIGHT_REGULAR;
+ break;
+ case FW_BOLD:
+ weight.u.i = FC_WEIGHT_BOLD;
+ break;
+ }
+ FcPatternAdd(pattern, FC_WEIGHT, weight, FcFalse);
+ FcFontSet *set = FcFontList(NULL, pattern, obj);
+ FcChar8 *file;
+ for (int i=0; i<set->nfont; i++) {
+ if (FcPatternGetString(set->fonts[i], FC_FILE, 0, &file) == FcResultMatch) {
+ if (!file_extension_is_ttc((const char *)file)) {
+ filepath = strdup((const char *)file);
+ break;
+ }
+ }
+ }
+ FcObjectSetDestroy(obj);
+ FcPatternDestroy(pattern);
+ FcFontSetDestroy(set);
+ return filepath;
+}
+
+/* int main(int argc, char *argv[])
+{
+ struct Font font = {
+ .name = "LiberationMono",
+ .family = FF_NORMAL,
+ .style = FS_ITALIC,
+ .weight = FW_BOLD,
+ .size = 0.0
+ };
+ fontconfig_fontpath_find(&font);
+ return 0;
+} */
diff --git a/fontconfig.h b/fontconfig.h
@@ -0,0 +1,8 @@
+#include "chordpro.h"
+
+enum FontType {
+ FT_TTF,
+ FT_OTF
+};
+
+char *fontconfig_fontpath_find(struct Font *font, enum FontType font_type);
diff --git a/lorid.c b/lorid.c
@@ -4,12 +4,15 @@
#include <stdint.h>
#include <string.h>
#include <getopt.h>
+#include "config.h"
#include "chordpro.h"
#include "out_pdf.h"
-#include "config.h"
int main(int argc, char *argv[])
{
+ char *new = cho_font_name_sanitize("Noto Sans");
+ printf("new: %s\n", new);
+ free(new);
static struct option long_options[] = {
{ "print-default-config", no_argument, 0, 'p' },
{ "config", required_argument, 0, 'c' },
@@ -35,7 +38,6 @@ int main(int argc, char *argv[])
return 1;
}
free(config_filepath);
- config_free(config);
if (argc == optind) {
fp = stdin;
} else if (argc == optind+1) {
@@ -53,11 +55,12 @@ int main(int argc, char *argv[])
fprintf(stderr, "cho_parse failed.\n");
return 1;
}
- if (!out_pdf_new(argv[1], songs)) {
+ if (!out_pdf_new(argv[1], songs, config)) {
fprintf(stderr, "out_pdf_new failed.\n");
return 1;
}
cho_songs_free(songs);
+ config_free(config);
fclose(fp);
return 0;
}
diff --git a/out_pdf.c b/out_pdf.c
@@ -4,38 +4,29 @@
#include <pdfio.h>
#include <pdfio-content.h>
#include "chordpro.h"
+#include "config.h"
#include "out_pdf.h"
+#include "fontconfig.h"
-static char current_font[17];
+static struct Fnt **g_fonts = NULL;
+
+static char current_font[200];
static double current_font_size;
static double current_y = MEDIABOX_HEIGHT - 25.0;
static pdfio_obj_t *current_font_obj = NULL;
-static pdfio_obj_t *inter_regular;
-static pdfio_obj_t *inter_bold;
-static pdfio_obj_t *inter_italic;
-static pdfio_obj_t *inter_bold_italic;
-static pdfio_obj_t *inter_light;
-static pdfio_obj_t *inter_light_italic;
-static pdfio_obj_t *get_font_obj_by_name(const char *name)
+static pdfio_obj_t *out_pdf_fnt_obj_get_by_name(const char *name)
{
- if (strcmp(name, "Inter-Regular") == 0) {
- return inter_regular;
- } else if (strcmp(name, "Inter-Bold") == 0) {
- return inter_bold;
- } else if (strcmp(name, "Inter-Italic") == 0) {
- return inter_italic;
- } else if (strcmp(name, "Inter-BoldItalic") == 0) {
- return inter_bold_italic;
- } else if (strcmp(name, "Inter-Light") == 0) {
- return inter_light;
- } else if (strcmp(name, "Inter-LightItalic") == 0) {
- return inter_light_italic;
+ int i = 0;
+ while (g_fonts[i] != NULL) {
+ if (strcmp(g_fonts[i]->name, name) == 0)
+ return g_fonts[i]->font;
+ i++;
}
return NULL;
}
-char *out_pdf_concat_line_items(struct ChoLineItem **items)
+static char *out_pdf_concat_line_items(struct ChoLineItem **items)
{
char *line = NULL;
int size = 1;
@@ -57,24 +48,7 @@ char *out_pdf_concat_line_items(struct ChoLineItem **items)
return line;
}
-static bool out_pdf_font_set(pdfio_stream_t *stream, const char *name, double size)
-{
- if (!pdfioContentSetTextFont(stream, name, size)) {
- fprintf(stderr, "pdfioContentSetTextFont failed.\n");
- return false;
- }
- if (strlen(name) > 17)
- return false;
- pdfio_obj_t *font_obj = get_font_obj_by_name(name);
- if (font_obj == NULL)
- return false;
- strcpy(current_font, name);
- current_font_obj = font_obj;
- current_font_size = size;
- return true;
-}
-
-char *string_trim(const char *text)
+static char *string_trim(const char *text)
{
char *trimmed_text = NULL;
int begin = 0;
@@ -115,30 +89,7 @@ char *string_trim(const char *text)
return trimmed_text;
}
-/* static void out_pdf_font_find(struct Font *font)
-{
- FcInit();
- FcObjectSet *obj = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_FILE);
- FcPattern *pattern = FcPatternCreate();
- FcValue value = { .type = FcTypeString, .u.s = (unsigned char *)font->name };
- FcPatternAdd(pattern, FC_FAMILY, value, FcFalse);
- FcFontSet *set = FcFontList(NULL, pattern, obj);
- for (int i=0; i<set->nfont; i++) {
- FcChar8 *style, *filepath;
- if (FcPatternGetString(set->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) {
- printf("style: %s\n", style);
- if (FcPatternGetString(set->fonts[i], FC_FILE, 0, &filepath) == FcResultMatch) {
- printf("filepath: %s\n", filepath);
- }
- }
- }
- FcFontSetDestroy(set);
- FcObjectSetDestroy(obj);
- FcPatternDestroy(pattern);
- FcFini();
-} */
-
-static void out_pdf_font_add(struct Font *font, struct Font ***array)
+/* static void out_pdf_font_add(struct Font *font, struct Font ***array)
{
int a = 0;
if (!*array) {
@@ -152,7 +103,7 @@ static void out_pdf_font_add(struct Font *font, struct Font ***array)
(*array)[a] = font;
(*array)[a+1] = NULL;
}
-}
+} */
static bool out_pdf_font_add_if_not_in(struct Font *font, struct Font ***array)
{
@@ -224,7 +175,7 @@ static void out_pdf_add_fonts(struct Font *font, struct Font ***fonts)
cho_font_free(new_font);
}
-static void out_pdf_fonts_add_default(struct Font ***fonts)
+/* static void out_pdf_fonts_add_default(struct Font ***fonts)
{
struct Font *font_regular = cho_font_new();
font_regular->name = strdup("Inter");
@@ -242,12 +193,46 @@ static void out_pdf_fonts_add_default(struct Font ***fonts)
font_italic_bold->style = FS_ITALIC;
font_italic_bold->weight = FW_BOLD;
out_pdf_font_add(font_italic_bold, fonts);
-}
+} */
-static struct Font **out_pdf_font_get_all(struct ChoSong **songs)
+static struct Font **out_pdf_font_get_all(struct ChoSong **songs, struct Config *config)
{
struct Font **fonts = NULL;
- out_pdf_fonts_add_default(&fonts);
+ struct Font *font;
+ // out_pdf_fonts_add_default(&fonts);
+ bool added = false;
+ font = cho_font_duplicate(config->title_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->text_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->chord_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->comment_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->comment_italic_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->comment_box_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->tab_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
+ font = cho_font_duplicate(config->grid_font);
+ added = out_pdf_font_add_if_not_in(font, &fonts);
+ if (!added)
+ cho_font_free(font);
int so = 0;
int se = 0;
int li = 0;
@@ -280,7 +265,7 @@ static bool out_pdf_chord_show(pdfio_stream_t *stream, const char *lyrics_line,
char *line = malloc((strlen(lyrics_line)+1) * sizeof(char));
strcpy(line, lyrics_line);
line[chord->position] = 0;
- double width = pdfioContentTextMeasure(inter_regular, line, 16);
+ double width = pdfioContentTextMeasure(current_font_obj, line, current_font_size);
free(line);
if (!pdfioContentTextBegin(stream)) {
fprintf(stderr, "pdfioContentTextBegin failed.\n");
@@ -354,7 +339,7 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, const char *str, enum Alig
{
} */
-static char *out_pdf_filename(const char *old)
+static char *out_pdf_filename_create(const char *old)
{
char *new = NULL;
int mark = -1;
@@ -392,54 +377,159 @@ static char *out_pdf_filename(const char *old)
return new;
}
-bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
+static struct Fnt *out_pdf_fnt_new(void)
{
- char *pdf_filename = out_pdf_filename(cho_filename);
- 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 };
- pdfio_file_t *pdf = pdfioFileCreate(pdf_filename, "2.0", &media_box_a4, &crop_box, NULL, NULL);
- free(pdf_filename);
- pdfio_dict_t *page1_dict = pdfioDictCreate(pdf);
- struct Font **fonts = out_pdf_font_get_all(songs);
- int f = 0;
- while (fonts[f] != NULL) {
- cho_font_print(fonts[f]);
- // out_pdf_font_find(fonts[f]);
- f++;
+ struct Fnt *fnt = malloc(sizeof(struct Fnt));
+ fnt->name = NULL;
+ fnt->font = NULL;
+ return fnt;
+}
+
+static char *out_pdf_fnt_name_create(struct Font *font)
+{
+ char *name = cho_font_name_sanitize(font->name);
+ const char *family = cho_font_family_to_string(font->family);
+ const char *style = cho_font_style_to_string(font->style);
+ const char *weight = cho_font_weight_to_string(font->weight);
+ int n = 0;
+ int i = 0;
+ char *fnt_name = malloc((strlen(name) + strlen(family) + strlen(style) + strlen(weight) + 4) * sizeof(char));
+ while (name[i] != 0) {
+ fnt_name[n] = name[i];
+ n++;
+ i++;
}
- cho_fonts_free(fonts);
- inter_regular = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-Regular.ttf", true);
- inter_bold = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-Bold.ttf", true);
- inter_italic = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-Italic.ttf", true);
- inter_bold_italic = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-BoldItalic.ttf", true);
- inter_light = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-Light.ttf", true);
- inter_light_italic = pdfioFileCreateFontObjFromFile(pdf, "./fonts/Inter-LightItalic.ttf", true);
- if (!pdfioPageDictAddFont(page1_dict, "Inter-Regular", inter_regular)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
- return false;
+ i = 0;
+ fnt_name[n] = '-';
+ n++;
+ while (family[i] != 0) {
+ fnt_name[n] = family[i];
+ n++;
+ i++;
}
- if (!pdfioPageDictAddFont(page1_dict, "Inter-Bold", inter_bold)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
- return false;
+ i = 0;
+ fnt_name[n] = '-';
+ n++;
+ while (style[i] != 0) {
+ fnt_name[n] = style[i];
+ n++;
+ i++;
}
- if (!pdfioPageDictAddFont(page1_dict, "Inter-Italic", inter_italic)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
- return false;
+ i = 0;
+ fnt_name[n] = '-';
+ n++;
+ while (weight[i] != 0) {
+ fnt_name[n] = weight[i];
+ n++;
+ i++;
}
- if (!pdfioPageDictAddFont(page1_dict, "Inter-BoldItalic", inter_bold_italic)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
- return false;
+ fnt_name[n] = 0;
+ free(name);
+ return fnt_name;
+}
+
+static void out_pdf_fnt_free(struct Fnt *fnt)
+{
+ free(fnt->name);
+ free(fnt);
+}
+
+static void out_pdf_fnts_free(struct Fnt **fnts)
+{
+ int i = 0;
+ while (fnts[i] != NULL) {
+ out_pdf_fnt_free(fnts[i]);
+ i++;
+ }
+ free(fnts);
+}
+
+static void out_pdf_fnt_add(struct Fnt *fnt, struct Fnt ***array)
+{
+ int a = 0;
+ if (!*array) {
+ *array = realloc(*array, 2 * sizeof(struct Fnt *));
+ (*array)[0] = fnt;
+ (*array)[1] = NULL;
+ } else {
+ while ((*array)[a] != NULL)
+ a++;
+ *array = realloc(*array, (a+2) * sizeof(struct Fnt *));
+ (*array)[a] = fnt;
+ (*array)[a+1] = NULL;
}
- if (!pdfioPageDictAddFont(page1_dict, "Inter-Light", inter_light)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
+}
+
+static bool out_pdf_font_set(pdfio_stream_t *stream, struct Font *font)
+{
+ char *name = out_pdf_fnt_name_create(font);
+ if (!pdfioContentSetTextFont(stream, name, font->size)) {
+ fprintf(stderr, "pdfioContentSetTextFont failed.\n");
return false;
}
- if (!pdfioPageDictAddFont(page1_dict, "Inter-LightItalic", inter_light_italic)) {
- fprintf(stderr, "pdfioPageDictAddFont failed.\n");
+ pdfio_obj_t *font_obj = out_pdf_fnt_obj_get_by_name(name);
+ if (font_obj == NULL)
return false;
+ strcpy(current_font, name);
+ current_font_obj = font_obj;
+ current_font_size = font->size;
+ free(name);
+ return true;
+}
+
+bool out_pdf_new(const char *cho_filename, struct ChoSong **songs, struct Config *config)
+{
+ char *pdf_filename = out_pdf_filename_create(cho_filename);
+ printf("pdf: %s\n", pdf_filename);
+ 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 };
+ pdfio_file_t *pdf = pdfioFileCreate(pdf_filename, "2.0", &media_box_a4, &crop_box, NULL, NULL);
+ free(pdf_filename);
+ pdfio_dict_t *page1_dict = pdfioDictCreate(pdf);
+ struct Font **needed_fonts = out_pdf_font_get_all(songs, config);
+ struct Fnt *fnt;
+ int f = 0;
+ char *fontpath;
+ while (needed_fonts[f] != NULL) {
+ fontpath = fontconfig_fontpath_find(needed_fonts[f], FT_TTF);
+ if (fontpath) {
+ fnt = out_pdf_fnt_new();
+ fnt->name = out_pdf_fnt_name_create(needed_fonts[f]);
+ fnt->font = pdfioFileCreateFontObjFromFile(pdf, fontpath, true);
+ out_pdf_fnt_add(fnt, &g_fonts);
+ if (!pdfioPageDictAddFont(page1_dict, fnt->name, fnt->font)) {
+ fprintf(stderr, "pdfioPageDictAddFont failed.\n");
+ return false;
+ }
+ free(fontpath);
+ } else {
+ fontpath = fontconfig_fontpath_find(needed_fonts[f], FT_OTF);
+ if (fontpath) {
+ fnt = out_pdf_fnt_new();
+ fnt->name = out_pdf_fnt_name_create(needed_fonts[f]);
+ fnt->font = pdfioFileCreateFontObjFromFile(pdf, fontpath, true);
+ out_pdf_fnt_add(fnt, &g_fonts);
+ if (!pdfioPageDictAddFont(page1_dict, fnt->name, fnt->font)) {
+ fprintf(stderr, "pdfioPageDictAddFont failed.\n");
+ return false;
+ }
+ free(fontpath);
+ } else {
+ fprintf(stderr, "INFO: Didn't find font file for following font:\n");
+ cho_font_print(needed_fonts[f]);
+ return false;
+ }
+ }
+ f++;
+ }
+ cho_fonts_free(needed_fonts);
+ f = 0;
+ while (g_fonts[f] != NULL) {
+ printf("name: %s\n", g_fonts[f]->name);
+ f++;
}
pdfio_stream_t *page1_stream = pdfioFileCreatePage(pdf, page1_dict);
- if (!out_pdf_font_set(page1_stream, "Inter-Regular", 14.0)) {
+ if (!out_pdf_font_set(page1_stream, config->text_font)) {
fprintf(stderr, "out_pdf_font_set failed.\n");
return false;
}
@@ -472,7 +562,7 @@ bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
if (strcmp(songs[so]->metadata[m]->name, "title") == 0) {
const char *title = songs[so]->metadata[m]->value;
pdfioFileSetTitle(pdf, title);
- if (!out_pdf_font_set(page1_stream, "Inter-Bold", 18.0)) {
+ if (!out_pdf_font_set(page1_stream, config->title_font)) {
fprintf(stderr, "out_pdf_font_set failed.\n");
return false;
}
@@ -491,7 +581,7 @@ bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
while (songs[so]->sections[se] != NULL) {
if (songs[so]->sections[se]->name) {
const char *section_name = songs[so]->sections[se]->name;
- if (!out_pdf_font_set(page1_stream, "Inter-Italic", 14.0)) {
+ if (!out_pdf_font_set(page1_stream, config->comment_italic_font)) {
fprintf(stderr, "out_pdf_font_set failed.\n");
return false;
}
@@ -504,7 +594,7 @@ bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
chords = songs[so]->sections[se]->lines[li]->chords;
int count = cho_chord_count(chords);
if (count > 0) {
- if (!out_pdf_font_set(page1_stream, "Inter-Bold", 15.0)) {
+ if (!out_pdf_font_set(page1_stream, config->chord_font)) {
fprintf(stderr, "out_pdf_font_set failed.\n");
return false;
}
@@ -525,7 +615,7 @@ bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
}
char *text;
int items_count = cho_line_item_count(songs[so]->sections[se]->lines[li]->lyrics);
- if (!out_pdf_font_set(page1_stream, "Inter-Regular", 16.0)) {
+ if (!out_pdf_font_set(page1_stream, config->text_font)) {
fprintf(stderr, "out_pdf_font_set failed.\n");
return false;
}
@@ -561,5 +651,6 @@ bool out_pdf_new(const char *cho_filename, struct ChoSong **songs)
fprintf(stderr, "pdfioFileClose failed.\n");
return false;
}
+ out_pdf_fnts_free(g_fonts);
return true;
}
diff --git a/out_pdf.h b/out_pdf.h
@@ -1,3 +1,5 @@
+#include <pdfio.h>
+
#define MEDIABOX_HEIGHT 842.0
#define MEDIABOX_WIDTH 595.0
#define PAGE_HEIGHT MEDIABOX_HEIGHT - 36.0
@@ -11,9 +13,9 @@ enum Alignment {
CONTINUE
};
-struct FontObj {
+struct Fnt {
char *name;
- // pdfio_obj_t
+ pdfio_obj_t *font;
};
-bool out_pdf_new(const char *cho_filename, struct ChoSong **songs);
+bool out_pdf_new(const char *cho_filename, struct ChoSong **songs, struct Config *config);
diff --git a/todo b/todo
@@ -10,3 +10,4 @@ chordpro markup
the whole chords advanced stuff
transpose
define chords
+ chord diagrams