#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include "svg-track.inc.c"
#include "svg-save.inc.c"
typedef struct {
const char *base;
const char *link0;
const char *link1;
} Link;
typedef struct {
const char *name;
Link begin;
const char *mid;
Link end;
int linkMode;
const char *alias;
} Letter;
#include "letters.inc.c"
char path[1024*1024];
double pathX0 = 60, pathRowStep = 200, pathWidth = 5;
char *pathEnd;
double pathX, pathY;
FILE *pathFile;
int pathMode;
void putPath(const char *str) {
if (!str || !*str) return;
if (!*path) {
char buf[256] = {};
sprintf(buf, "M %g %g ", pathX, pathY);
char *c = buf;
while(*c) *pathEnd++ = *c++;
}
spTrack(str, &pathX, &pathY);
while(*str) *pathEnd++ = *str++;
*pathEnd = 0;
}
void splitPath(int mode) {
if (mode >= 2) {
if (pathMode >= 2) {
if (*path) svgAddPath(pathFile, path, pathWidth, 1);
*(pathEnd = path) = 0;
}
} else
if (mode >= 1) {
pathX = pathX0;
pathY += pathRowStep;
if (pathMode >= 1) {
if (*path) svgAddPath(pathFile, path, pathWidth, 1);
*(pathEnd = path) = 0;
} else
if (*path) {
char buf[256] = {};
sprintf(buf, "M %g %g ", pathX, pathY);
putPath(buf);
}
} else {
if (*path) svgAddPath(pathFile, path, pathWidth, 1);
//*(pathEnd = path) = 0;
}
}
void textToPath(const char *text) {
pathEnd = path;
*pathEnd = 0;
int cnt = sizeof(letters)/sizeof(*letters);
Letter *prev = NULL;
while(*text) {
Letter *curr = NULL;
do {
for(int i = 0; i < cnt; ++i) {
Letter *l = &letters[i];
const char *t = curr ? curr->alias : text;
const char *ln = l->name;
while(*t && *ln && *t == *ln) ++t, ++ln;
if (!*ln) {
if (!curr) text = t;
curr = l;
break;
}
}
} while(curr && curr->alias);
if (prev) {
const char *link = curr && curr->linkMode == 1 ? prev->end.link1 : prev->end.link0;
putPath(curr && curr->linkMode != 2 && curr->linkMode != 3 && link ? link : prev->end.base);
}
splitPath(2);
if (curr) {
const char *link = curr->linkMode == 1 ? curr->begin.link1 : curr->begin.link0;
putPath(prev && prev->linkMode != 2 && link ? link : curr->begin.base);
putPath(curr->mid);
} else
if (*text == '\n') {
splitPath(1);
++text;
} else {
putPath(MSPACE);
++text;
}
prev = curr;
}
if (prev) putPath(prev->end.base);
splitPath(0);
}
int textFileToSVG(const char *textfile, const char *svgfile) {
FILE *sf = fopen(textfile, "r");
if (!sf) {
fprintf(stderr, "cannot open file '%s' for read\n", textfile);
return 1;
}
char buf[1024*1024] = {};
char *str = buf, *end = buf + sizeof(buf) - 1;
while(1) {
int c = fgetc(sf);
if (c <= 0) break;
*str++ = c;
if (str == end) {
fprintf(stderr, "input file '%s' too large\n", textfile);
return 1;
}
}
fclose(sf);
pathX = pathX0;
pathY = pathRowStep;
pathEnd = path;
pathFile = svgBegin(svgfile, 300, 300, 10);
if (!pathFile) {
fprintf(stderr, "cannot open file '%s' for write\n", svgfile);
return 1;
}
pathMode = 2;
textToPath(buf);
svgEnd(pathFile);
pathX = pathX0;
pathY = pathRowStep;
pathEnd = path;
pathFile = NULL;
return 0;
}
int main(int argc, char **argv) {
if (argc != 3) {
printf("usage: writing <input-text-file> <output-svg-file>\n");
return 1;
}
return textFileToSVG(argv[1], argv[2]);
}