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:
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) {