lorid

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

commit e222d71f1a0956e71f030c26d09681ca9df24e54
parent 73075728f23c64e56bffe38883a1cf0c84c4d349
Author: nibo <nibo@relim.de>
Date:   Tue, 11 Feb 2025 12:09:17 +0100

Improve font handling

- make variable 'DEFAULT_FONT'
- Center the chord name above a chord diagram in case of a base font
- Allow bold, italic and oblique when using a base font

Diffstat:
MMakefile | 12++++++++----
MREADME.md | 8++++----
Msrc/chord_diagram.c | 10++++++++++
Msrc/chord_diagram.h | 1+
Msrc/config.c | 26+++++++++++++-------------
Msrc/config.h | 1-
Msrc/out_pdf.c | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
7 files changed, 102 insertions(+), 53 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,14 +1,18 @@ -VERSION = 0.1.0 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man -# Control whether log messages are colored. -COLOR = 0 -VARS = -DVERSION=\"${VERSION}\" -DCOLOR=${COLOR} -DPREFIX=\"${PREFIX}\" CFLAGS = -std=c23 -pedantic -Wall -Wextra LDFLAGS = -lpdfio -ltoml -lfontconfig -lgrapheme -lm STATIC_LDFLAGS = -lpdfio -ltoml -lfontconfig -lgrapheme -lz -L/home/robin/src/libexpat/expat/lib/.libs/ -lexpat -L/home/robin/src/freetype/build/ -lfreetype -L/home/robin/src/libpng-1.6.45/.libs/ -lpng16 -L/home/robin/src/harfbuzz/build/src/ -lharfbuzz -lm SRC = src/util.c src/config.c src/chordpro.c src/chord_diagram.c src/out_pdf.c src/lorid.c +VERSION = 0.1.0 +# Control whether log messages are colored. +COLOR = 0 +# Exact font family name, e.g. from `fc-list : family` +DEFAULT_FONT = "Helvetica" +# DEFAULT_FONT = "Open Sans" +VARS = -DDEFAULT_FONT=\"${DEFAULT_FONT}\" -DVERSION=\"${VERSION}\" -DCOLOR=${COLOR} -DPREFIX=\"${PREFIX}\" + compile: $(CC) ${CFLAGS} ${VARS} -O2 ${SRC} -o lorid ${LDFLAGS} static: diff --git a/README.md b/README.md @@ -51,10 +51,10 @@ Website: `https://www.freedesktop.org/wiki/Software/fontconfig/` You probably already have it installed. You can verify that by running: ``` -[~] ls -l /usr/lib/libfontconfig* -lrwxrwxrwx 1 root root 18 Jan 23 02:37 /usr/lib/libfontconfig.so -> libfontconfig.so.1 -lrwxrwxrwx 1 root root 23 Jan 23 02:37 /usr/lib/libfontconfig.so.1 -> libfontconfig.so.1.15.0 --rwxr-xr-x 1 root root 321496 Jan 23 02:37 /usr/lib/libfontconfig.so.1.15.0 +[~] find /usr/lib -name 'libfontconfig*' +/usr/lib/libfontconfig.so.1.15.0 +/usr/lib/libfontconfig.so.1 +/usr/lib/libfontconfig.so [~] ``` If an '*.so' file exists it's already installed. diff --git a/src/chord_diagram.c b/src/chord_diagram.c @@ -10,6 +10,13 @@ #include "chord_diagram.h" #include "diagrams.h" +static bool g_is_base_font = false; + +void chord_diagram_set_base_font(bool is_base_font) +{ + g_is_base_font = is_base_font; +} + static bool text_show( pdfio_stream_t *stream, @@ -490,6 +497,9 @@ string_diagram_draw( fprintf(stderr, "pdfioContentSetTextFont failed.\n"); return false; } + if (g_is_base_font) { + centered_x -= width / 10.0; + } if (!text_show(stream, diagram->name, x+centered_x, y_above_diagram + 7.0)) { fprintf(stderr, "text_show failed.\n"); return false; diff --git a/src/chord_diagram.h b/src/chord_diagram.h @@ -12,6 +12,7 @@ enum Direction { VERTICAL }; +void chord_diagram_set_base_font(bool is_base_font); struct ChordDiagram *chord_diagram_new(); void chord_diagram_free(struct ChordDiagram *d); bool chord_diagram_draw(pdfio_stream_t *stream, struct ChordDiagram *diagram, double x, double y, double width); diff --git a/src/config.c b/src/config.c @@ -435,49 +435,49 @@ config_load_default(void) config->output->styles = emalloc(TT_LENGTH * sizeof(struct ChoStyle *)); config->output->styles[TT_CHORD] = cho_style_new(); - config->output->styles[TT_CHORD]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_CHORD]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_CHORD]->font->weight = FW_BOLD; config->output->styles[TT_ANNOT] = cho_style_new(); - config->output->styles[TT_ANNOT]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_ANNOT]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_ANNOT]->font->style = FS_ITALIC; config->output->styles[TT_CHORUS] = cho_style_new(); - config->output->styles[TT_CHORUS]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_CHORUS]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_FOOTER] = cho_style_new(); config->output->styles[TT_GRID] = cho_style_new(); - config->output->styles[TT_GRID]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_GRID]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_GRID]->font->weight = FW_BOLD; config->output->styles[TT_TAB] = cho_style_new(); config->output->styles[TT_TAB]->font->name = strdup("Courier"); // config->output->styles[TT_TAB]->font->family = FF_MONOSPACE; config->output->styles[TT_TOC] = cho_style_new(); - config->output->styles[TT_TOC]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_TOC]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_TOC]->font->size = 12.0; config->output->styles[TT_TOC_TITLE] = cho_style_new(); - config->output->styles[TT_TOC_TITLE]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_TOC_TITLE]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_TOC_TITLE]->font->weight = FW_BOLD; config->output->styles[TT_TOC_TITLE]->font->size = 18.0; config->output->styles[TT_TEXT] = cho_style_new(); - config->output->styles[TT_TEXT]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_TEXT]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_TITLE] = cho_style_new(); - config->output->styles[TT_TITLE]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_TITLE]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_TITLE]->font->weight = FW_BOLD; config->output->styles[TT_TITLE]->font->size = 18.0; config->output->styles[TT_SUBTITLE] = cho_style_new(); - config->output->styles[TT_SUBTITLE]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_SUBTITLE]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_SUBTITLE]->font->size = 12.0; config->output->styles[TT_LABEL] = cho_style_new(); - config->output->styles[TT_LABEL]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_LABEL]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_LABEL]->font->style = FS_ITALIC; config->output->styles[TT_COMMENT] = cho_style_new(); - config->output->styles[TT_COMMENT]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_COMMENT]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_COMMENT]->background_color->red = 228; config->output->styles[TT_COMMENT]->background_color->green = 228; config->output->styles[TT_COMMENT]->background_color->blue = 228; config->output->styles[TT_COMMENT_ITALIC] = cho_style_new(); - config->output->styles[TT_COMMENT_ITALIC]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_COMMENT_ITALIC]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_COMMENT_ITALIC]->font->style = FS_ITALIC; config->output->styles[TT_COMMENT_BOX] = cho_style_new(); - config->output->styles[TT_COMMENT_BOX]->font->name = strdup(DEFAULT_FONT_FAMILY); + config->output->styles[TT_COMMENT_BOX]->font->name = strdup(DEFAULT_FONT); config->output->styles[TT_COMMENT_BOX]->boxed = true; // config->output->styles[15] = NULL; diff --git a/src/config.h b/src/config.h @@ -8,7 +8,6 @@ #else #define SYMBOLS_FILEPATH PREFIX"/share/lorid/ChordProSymbols.ttf" #endif /* DEBUG */ -#define DEFAULT_FONT_FAMILY "Open Sans" struct Config *config_load(const char *filepath); void config_free(struct Config *config); diff --git a/src/out_pdf.c b/src/out_pdf.c @@ -23,23 +23,6 @@ static int g_current_page_index; static pdfio_file_t *g_pdf_file = NULL; static struct Config *g_config = NULL; -static const char *g_base_fonts[] = { - "Courier", - "Courier-Bold", - "Courier-BoldItalic", - "Courier-Italic", - "Helvetica", - "Helvetica-Bold", - "Helvetica-BoldOblique", - "Helvetica-Oblique", - "Symbol", - "Times-Bold", - "Times-BoldItalic", - "Times-Italic", - "Times-Roman", - "ZapfDingbats" -}; - static struct Obj * obj_new(void) { @@ -333,13 +316,77 @@ fontpath_find(struct Font *font, enum FontType font_type) return filepath; } +static const char * +is_base_font(struct Font *font) +{ + if (!strcmp(font->name, "Courier")) { + if (font->style == FS_ITALIC && font->weight == FW_BOLD) { + return "Courier-BoldItalic"; + } else + if (font->style == FS_ITALIC) { + return "Courier-Italic"; + } else + if (font->weight == FW_BOLD) { + return "Courier-Bold"; + } + return "Courier"; + } else + if (!strcmp(font->name, "Helvetica")) { + if (font->style == FS_OBLIQUE && font->weight == FW_BOLD) { + return "Helvetica-BoldOblique"; + } else + if (font->style == FS_OBLIQUE) { + return "Helvetica-Oblique"; + } else + if (font->weight == FW_BOLD) { + return "Helvetica-Bold"; + } + return "Helvetica"; + } else + if (!strcmp(font->name, "Times")) { + if (font->style == FS_ITALIC && font->weight == FW_BOLD) { + return "Times-BoldItalic"; + } else + if (font->style == FS_ITALIC) { + return "Times-Italic"; + } else + if (font->weight == FW_BOLD) { + return "Times-Bold"; + } + return "Times-Roman"; + } + return NULL; +} + static bool pdf_load_chord_diagram_fonts(void) { struct Obj *fnt; + char *fontpath; + const char *font_name; + struct Font font = { + .name = DEFAULT_FONT, + .family = FF_NORMAL, + .style = FS_ROMAN, + .weight = FW_REGULAR + }; fnt = obj_new(); fnt->name = strdup("chord-diagram-regular-font"); - fnt->value = pdfioFileCreateFontObjFromBase(g_pdf_file, "Helvetica"); + if ((font_name = is_base_font(&font))) { + fnt->value = pdfioFileCreateFontObjFromBase(g_pdf_file, font_name); + chord_diagram_set_base_font(true); + } else { + fontpath = fontpath_find(&font, FT_TTF); + if (!fontpath) { + fontpath = fontpath_find(&font, FT_OTF); + if (!fontpath) { + LOG_DEBUG("fontpath_find failed."); + return false; + } + } + fnt->value = pdfioFileCreateFontObjFromFile(g_pdf_file, fontpath, true); + free(fontpath); + } objs_add_obj(&g_fonts, fnt); fnt = obj_new(); fnt->name = strdup("chord-diagram-symbols"); @@ -348,18 +395,6 @@ pdf_load_chord_diagram_fonts(void) return true; } -static const char * -is_base_font(struct Font *font) -{ - int i; - for (i = 0; i<14; i++) { - if (!strcmp(font->name, g_base_fonts[i])) { - return g_base_fonts[i]; - } - } - return NULL; -} - static bool font_name_is_path(const char *name) { @@ -1770,7 +1805,7 @@ pdf_page_add_page_no(struct PDFContext *ctx, enum NumeralSystem numeral_system) double width, x; style = cho_style_new(); - style->font->name = strdup(DEFAULT_FONT_FAMILY); + style->font->name = strdup(DEFAULT_FONT); texts = &ctx->content->pages[ctx->page]->texts; page_no = numeral_system_number_to_str(numeral_system, ctx->page+1); if (!page_no) {