commit f93d5da85c69214eac0c7b9b7a8ecf5771654af7
parent e321cff419173fb31c3dece2b5900079b170d7da
Author: nibo <nibo@relim.de>
Date: Tue, 30 Jul 2024 21:59:44 +0200
Implement more style options when generating pdf
Diffstat:
| M | Makefile | | | 4 | ++-- |
| M | chordpro.c | | | 2 | +- |
| M | lorid.c | | | 2 | +- |
| M | out_pdf.c | | | 123 | +++++++++++-------------------------------------------------------------------- |
| M | out_pdf.h | | | 7 | ------- |
| D | str.c | | | 98 | ------------------------------------------------------------------------------- |
| D | str.h | | | 3 | --- |
| A | util.c | | | 184 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | util.h | | | 17 | +++++++++++++++++ |
9 files changed, 222 insertions(+), 218 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,7 @@
all:
- $(CC) -pedantic -Wall -Wextra -O2 str.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig
+ $(CC) -pedantic -Wall -Wextra -O2 util.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig
debug:
- $(CC) -g -pedantic -Wall -Wextra str.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -lpdfio -ltoml -lfontconfig
+ $(CC) -g -pedantic -Wall -Wextra util.c fontconfig.c config.c chordpro.c out_pdf.c lorid.c -o lorid -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
@@ -6,7 +6,7 @@
#include <ctype.h>
#include "chordpro.h"
#include "config.h"
-#include "str.h"
+#include "util.h"
static const char *environment_directives[] = {
"start_of_chorus", "soc", "end_of_chorus", "eoc", "chorus",
diff --git a/lorid.c b/lorid.c
@@ -7,7 +7,7 @@
#include "config.h"
#include "chordpro.h"
#include "out_pdf.h"
-#include "str.h"
+#include "util.h"
int main(int argc, char *argv[])
{
diff --git a/out_pdf.c b/out_pdf.c
@@ -1,14 +1,13 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
-#include <sys/stat.h>
#include <pdfio.h>
#include <pdfio-content.h>
#include "chordpro.h"
#include "config.h"
#include "out_pdf.h"
#include "fontconfig.h"
-#include "str.h"
+#include "util.h"
static struct Fnt **g_fonts = NULL;
@@ -172,105 +171,6 @@ static size_t out_pdf_text_find_fitting_length(const char *str, size_t len)
return len;
}
-static enum FileType file_type(const char *path)
-{
- struct stat s;
- if (stat(path, &s) != 0) {
- return F_ERROR;
- }
- switch (s.st_mode & S_IFMT) {
- case S_IFDIR:
- return F_FOLDER;
- case S_IFREG:
- return F_REG_FILE;
- }
- return F_OTHER;
-}
-
-static char *filepath_add_ending_slash_if_missing(const char *path)
-{
- size_t len = strlen(path);
- if (path[len-1] == '/') {
- return strdup(path);
- } else {
- char *path_with_slash = malloc((len+2) * sizeof(char));
- strcpy(path_with_slash, path);
- path_with_slash[len] = '/';
- path_with_slash[len+1] = 0;
- return path_with_slash;
- }
-}
-
-static char *filepath_basename(const char *path)
-{
- int begin = 0;
- int i;
- for (i = 0; path[i] != 0; i++) {
- if (path[i] == '/') {
- begin = i+1;
- }
- }
- return strdup(&path[begin]);
-}
-
-static char *filepath_dirname(const char *path)
-{
- char *dirname;
- int end = 0;
- int i;
- for (i = 0; path[i] != 0; i++) {
- if (path[i] == '/') {
- end = i;
- }
- }
- dirname = malloc((end+1)* sizeof(char));
- i = 0;
- while (i<end) {
- dirname[i] = path[i];
- i++;
- }
- dirname[i] = 0;
- return dirname;
-}
-
-static char *file_extension_replace_or_add(const char *old)
-{
- char *new = NULL;
- int mark = -1;
- int i = 0;
- int old_len;
- while (old[i] != 0) {
- if (old[i] == '.')
- mark = i;
- i++;
- }
- i = 0;
- if (mark == -1) {
- old_len = (int)strlen(old);
- new = malloc((old_len+5) * sizeof(char));
- while (i < old_len) {
- new[i] = old[i];
- i++;
- }
- new[i] = '.';
- new[++i] = 'p';
- new[++i] = 'd';
- new[++i] = 'f';
- new[++i] = 0;
- } else {
- new = malloc((mark+5) * sizeof(char));
- while (i <= mark) {
- new[i] = old[i];
- i++;
- }
- new[i] = 'p';
- new[++i] = 'd';
- new[++i] = 'f';
- new[++i] = 0;
- }
- return new;
-}
-
static char *out_pdf_filename_generate_from_songs(struct ChoSong **songs)
{
char *filename;
@@ -286,13 +186,11 @@ static char *out_pdf_filename_generate_from_songs(struct ChoSong **songs)
return NULL;
}
normalized_title = str_normalize(title);
- filename = file_extension_replace_or_add(normalized_title);
+ filename = file_extension_replace_or_add(normalized_title, "pdf");
free(normalized_title);
return filename;
}
return strdup("collection-of-songs.pdf");
- /* if (len > 1) {
- } */
}
static char *out_pdf_filename_create(struct ChoSong **songs, const char *cho_filepath, const char *out)
@@ -301,7 +199,7 @@ static char *out_pdf_filename_create(struct ChoSong **songs, const char *cho_fil
char *pdf_filename;
char *tmp;
if (cho_filepath) {
- pdf_filepath = file_extension_replace_or_add(cho_filepath);
+ pdf_filepath = file_extension_replace_or_add(cho_filepath, "pdf");
pdf_filename = filepath_basename(pdf_filepath);
} else {
pdf_filename = out_pdf_filename_generate_from_songs(songs);
@@ -484,13 +382,13 @@ static bool out_pdf_draw_line(pdfio_stream_t *stream, struct TextLineItem *item,
red = item->style->strikethrough_color->red / 255.0;
green = item->style->strikethrough_color->green / 255.0;
blue = item->style->strikethrough_color->blue / 255.0;
- printf("add to y: %.2f\n", item->style->font->size * 0.21);
y += item->style->font->size * 0.3;
break;
case LL_OVER:
red = item->style->overline_color->red / 255.0;
green = item->style->overline_color->green / 255.0;
blue = item->style->overline_color->blue / 255.0;
+ y += item->style->font->size * 0.8;
break;
}
if (!pdfioContentPathMoveTo(stream, item->x, y)) {
@@ -541,6 +439,10 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, struct TextLineItem *item,
fprintf(stderr, "pdfioContentTextMoveTo failed.\n");
return false;
}
+ if (!pdfioContentSetTextRise(stream, item->style->rise)) {
+ fprintf(stderr, "pdfioContentSetTextRise failed.\n");
+ return false;
+ }
if (!pdfioContentTextShow(stream, true, item->text)) {
fprintf(stderr, "pdfioContentTextShow failed.\n");
return false;
@@ -552,10 +454,19 @@ static bool out_pdf_text_show(pdfio_stream_t *stream, struct TextLineItem *item,
if (item->style->underline_style == LS_SINGLE) {
out_pdf_draw_line(stream, item, y, width, LL_UNDER);
} else if (item->style->underline_style == LS_DOUBLE) {
+ out_pdf_draw_line(stream, item, y, width, LL_UNDER);
+ out_pdf_draw_line(stream, item, y-1.5, width, LL_UNDER);
}
if (item->style->strikethrough) {
out_pdf_draw_line(stream, item, y, width, LL_STRIKETHROUGH);
}
+ if (item->style->overline_style == LS_SINGLE) {
+ out_pdf_draw_line(stream, item, y, width, LL_OVER);
+ } else if (item->style->overline_style == LS_DOUBLE) {
+ out_pdf_draw_line(stream, item, y, width, LL_OVER);
+ out_pdf_draw_line(stream, item, y+1.5, width, LL_OVER);
+ }
+ // TODO: Implement style->href and style->boxed
return true;
}
diff --git a/out_pdf.h b/out_pdf.h
@@ -38,13 +38,6 @@ struct Text {
struct TextLine **lines;
};
-enum FileType {
- F_ERROR,
- F_FOLDER,
- F_REG_FILE,
- F_OTHER
-};
-
enum LineLocation {
LL_OVER,
LL_STRIKETHROUGH,
diff --git a/str.c b/str.c
@@ -1,98 +0,0 @@
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include "str.h"
-
-/* char *str_normalize(const char *str)
-{
- char *normalized = NULL;
- int i = 0;
- int s = 0;
- char c;
- for (; str[i] != 0; i++) {
- if (str[i] == ' ')
- continue;
- c = (char)tolower(str[i]);
- normalized = realloc(normalized, (s+1) * sizeof(char));
- normalized[s] = c;
- s++;
- }
- normalized = realloc(normalized, (s+1) * sizeof(char));
- normalized[s] = 0;
- return normalized;
-} */
-
-char *str_normalize(const char *str)
-{
- char *normalized = NULL;
- int i = 0;
- int n = 0;
- char c;
- for (; str[i] != 0; i++) {
- if (str[i] == ' ') {
- normalized = realloc(normalized, (n+1) * sizeof(char));
- normalized[n] = '-';
- n++;
- continue;
- }
- if (str[i] == '\'' || str[i] == ',')
- continue;
- c = (char)tolower(str[i]);
- normalized = realloc(normalized, (n+1) * sizeof(char));
- normalized[n] = c;
- n++;
- }
- normalized = realloc(normalized, (n+1) * sizeof(char));
- normalized[n] = 0;
- return normalized;
-}
-
-char *str_trim(const char *str)
-{
- char *trimmed = NULL;
- int begin = 0;
- int end = 0;
- int len = (int)strlen(str);
- for (int i=0; i<len; i++) {
- if (
- str[i] == ' ' ||
- str[i] == '\n' ||
- str[i] == '\t' ||
- str[i] == '\r'
- )
- begin++;
- else
- break;
- }
- for (int i=len-1; i>=0; i--) {
- if (
- str[i] == ' '||
- str[i] == '\n' ||
- str[i] == '\t' ||
- str[i] == '\r'
- )
- end++;
- else
- break;
- }
- int k = 0;
- for (int i=0; i<len; i++) {
- if (i >= begin && i < len - end) {
- trimmed = realloc(trimmed, (k+1) * sizeof(char));
- trimmed[k] = str[i];
- k++;
- }
- }
- trimmed = realloc(trimmed, (k+1) * sizeof(char));
- trimmed[k] = 0;
- return trimmed;
-}
-
-char *str_remove_leading_whitespace(const char *str)
-{
- int i = 0;
- while (str[i] == ' ' || str[i] == '\t') {
- i++;
- }
- return strdup(&str[i]);
-}
diff --git a/str.h b/str.h
@@ -1,3 +0,0 @@
-char *str_normalize(const char *str);
-char *str_trim(const char *str);
-char *str_remove_leading_whitespace(const char *str);
diff --git a/util.c b/util.c
@@ -0,0 +1,184 @@
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <sys/stat.h>
+#include "util.h"
+
+char *str_normalize(const char *str)
+{
+ char *normalized = NULL;
+ int i = 0;
+ int n = 0;
+ char c;
+ for (; str[i] != 0; i++) {
+ if (str[i] == ' ') {
+ normalized = realloc(normalized, (n+1) * sizeof(char));
+ normalized[n] = '-';
+ n++;
+ continue;
+ }
+ if (str[i] == '\'' || str[i] == ',')
+ continue;
+ c = (char)tolower(str[i]);
+ normalized = realloc(normalized, (n+1) * sizeof(char));
+ normalized[n] = c;
+ n++;
+ }
+ normalized = realloc(normalized, (n+1) * sizeof(char));
+ normalized[n] = 0;
+ return normalized;
+}
+
+char *str_trim(const char *str)
+{
+ char *trimmed = NULL;
+ int begin = 0;
+ int end = 0;
+ int len = (int)strlen(str);
+ for (int i=0; i<len; i++) {
+ if (
+ str[i] == ' ' ||
+ str[i] == '\n' ||
+ str[i] == '\t' ||
+ str[i] == '\r'
+ )
+ begin++;
+ else
+ break;
+ }
+ for (int i=len-1; i>=0; i--) {
+ if (
+ str[i] == ' '||
+ str[i] == '\n' ||
+ str[i] == '\t' ||
+ str[i] == '\r'
+ )
+ end++;
+ else
+ break;
+ }
+ int k = 0;
+ for (int i=0; i<len; i++) {
+ if (i >= begin && i < len - end) {
+ trimmed = realloc(trimmed, (k+1) * sizeof(char));
+ trimmed[k] = str[i];
+ k++;
+ }
+ }
+ trimmed = realloc(trimmed, (k+1) * sizeof(char));
+ trimmed[k] = 0;
+ return trimmed;
+}
+
+char *str_remove_leading_whitespace(const char *str)
+{
+ int i = 0;
+ while (str[i] == ' ' || str[i] == '\t') {
+ i++;
+ }
+ return strdup(&str[i]);
+}
+
+enum FileType file_type(const char *path)
+{
+ struct stat s;
+ if (stat(path, &s) != 0) {
+ return F_ERROR;
+ }
+ switch (s.st_mode & S_IFMT) {
+ case S_IFDIR:
+ return F_FOLDER;
+ case S_IFREG:
+ return F_REG_FILE;
+ }
+ return F_OTHER;
+}
+
+char *file_extension_replace_or_add(const char *old, const char *extension)
+{
+ size_t extension_len = strlen(extension);
+ char *new = NULL;
+ int mark = -1;
+ int i = 0;
+ int e = 0;
+ int old_len;
+ while (old[i] != 0) {
+ if (old[i] == '.')
+ mark = i;
+ i++;
+ }
+ i = 0;
+ if (mark == -1) {
+ old_len = (int)strlen(old);
+ new = malloc((old_len+2+extension_len) * sizeof(char));
+ while (i < old_len) {
+ new[i] = old[i];
+ i++;
+ }
+ new[i] = '.';
+ while (extension[e] != 0) {
+ new[++i] = extension[e];
+ e++;
+ }
+ new[++i] = 0;
+ } else {
+ new = malloc((mark+2+extension_len) * sizeof(char));
+ while (i <= mark) {
+ new[i] = old[i];
+ i++;
+ }
+ while (extension[e] != 0) {
+ new[i] = extension[e];
+ i++;
+ e++;
+ }
+ new[i] = 0;
+ }
+ return new;
+}
+
+char *filepath_add_ending_slash_if_missing(const char *path)
+{
+ size_t len = strlen(path);
+ if (path[len-1] == '/') {
+ return strdup(path);
+ } else {
+ char *path_with_slash = malloc((len+2) * sizeof(char));
+ strcpy(path_with_slash, path);
+ path_with_slash[len] = '/';
+ path_with_slash[len+1] = 0;
+ return path_with_slash;
+ }
+}
+
+char *filepath_basename(const char *path)
+{
+ int begin = 0;
+ int i;
+ for (i = 0; path[i] != 0; i++) {
+ if (path[i] == '/') {
+ begin = i+1;
+ }
+ }
+ return strdup(&path[begin]);
+}
+
+char *filepath_dirname(const char *path)
+{
+ char *dirname;
+ int end = 0;
+ int i;
+ for (i = 0; path[i] != 0; i++) {
+ if (path[i] == '/') {
+ end = i;
+ }
+ }
+ dirname = malloc((end+1)* sizeof(char));
+ i = 0;
+ while (i<end) {
+ dirname[i] = path[i];
+ i++;
+ }
+ dirname[i] = 0;
+ return dirname;
+}
diff --git a/util.h b/util.h
@@ -0,0 +1,17 @@
+enum FileType {
+ F_ERROR,
+ F_FOLDER,
+ F_REG_FILE,
+ F_OTHER
+};
+
+char *str_normalize(const char *str);
+char *str_trim(const char *str);
+char *str_remove_leading_whitespace(const char *str);
+
+enum FileType file_type(const char *path);
+char *file_extension_replace_or_add(const char *old, const char *extension);
+
+char *filepath_add_ending_slash_if_missing(const char *path);
+char *filepath_basename(const char *path);
+char *filepath_dirname(const char *path);