Blame simple/writing/src/writing.c

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