Blame onefile/writing.c

Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#include <ctype.h>
Ivan Mahonin a5e8d6
#include <stdlib.h>
Ivan Mahonin a5e8d6
#include <stdio.h>
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#include <helianthus.h>
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#include "svg-path.inc.h"
Ivan Mahonin a5e8d6
#include "svg-save.inc.h"
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define MSPACE "m 60 0"
Ivan Mahonin a5e8d6
#define MDOTSP "m 20 0"
Ivan Mahonin a5e8d6
#define MUP  "m 10 -25 "
Ivan Mahonin a5e8d6
#define MUP3 "m 30 -75 "
Ivan Mahonin a5e8d6
#define MDN  "m -10 25 "
Ivan Mahonin a5e8d6
#define MUPE "m 4 -10 "
Ivan Mahonin a5e8d6
#define MDNE "m -4 10 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define Co1 "q 6 -15 -4 -15 "
Ivan Mahonin a5e8d6
#define Co2 "q -10 0 -16 15 "
Ivan Mahonin a5e8d6
#define Co3 "q -6 15 4 15 "
Ivan Mahonin a5e8d6
#define Co4 "q 10 0 16 -15 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CO1 "q 10 -25 -5 -25 "
Ivan Mahonin a5e8d6
#define CO2 "q -15 0 -25 25 "
Ivan Mahonin a5e8d6
#define CO3 "q -10 25 5 25 "
Ivan Mahonin a5e8d6
#define CO4 "q 15 0 25 -25 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CO1B "q 15 0 5 25 "
Ivan Mahonin a5e8d6
#define CO2B "q 10 -25 25 -25 "
Ivan Mahonin a5e8d6
#define CO3B "q -15 0 -5 -25 "
Ivan Mahonin a5e8d6
#define CO4B "q -10 25 -25 25 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CFO1 CO1 CO2 CO3 CO4
Ivan Mahonin a5e8d6
#define CFO2 CO2 CO3 CO4 CO1
Ivan Mahonin a5e8d6
#define CFO3 CO3 CO4 CO1 CO2
Ivan Mahonin a5e8d6
#define CFO4 CO4 CO1 CO2 CO3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CLU  "q 50 -50 30 0 "
Ivan Mahonin a5e8d6
#define CLD  "q -20 50 30 0 "
Ivan Mahonin a5e8d6
#define CLLD "q -10 25 0 25 q 15 0 40 -50 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CKD1 "c 14 -35 44 -35 38 -20 "
Ivan Mahonin a5e8d6
#define CKD2 "q -18 45 32 -5 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CJL0 "q -10 25 0 25 "
Ivan Mahonin a5e8d6
#define CJL  CJL0 "q 15 0 50 -50 "
Ivan Mahonin a5e8d6
#define CJR  CJL0 "c 15 0 40 -25 44 -35 " Co1 Co2 Co3 Co4 "l 6 -15 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CGD0 CLD CDN "q -10 25 -20 25 "
Ivan Mahonin a5e8d6
#define CGD  CGD0 "c -20 0 20 -25 45 -50 "
Ivan Mahonin a5e8d6
#define CGDE CGD0 "c -20 0 19 -25 39 -35 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CQU1 "c 25 -25 51 -40 61 -65 "
Ivan Mahonin a5e8d6
#define CQU2 "q 4 -10 -6 -10 q -10 0 -20 25 l -20 50 "
Ivan Mahonin a5e8d6
#define CQU  CQU1 CQU2
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CQD1  CDN2
Ivan Mahonin a5e8d6
#define CQD2  "q -10 25 -20 25 q -10 0 -6 -10 "
Ivan Mahonin a5e8d6
#define CQD3  "c 10 -25 36 -40 61 -65 "
Ivan Mahonin a5e8d6
#define CQD3E "c 10 -25 35 -40 55 -50 "
Ivan Mahonin a5e8d6
#define CQD CQD1 CQD2 CQD3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CC1 "q 5 0 8 5 "
Ivan Mahonin a5e8d6
#define CC2 "q -3 -5 -8 -5 " CO2 CO3
Ivan Mahonin a5e8d6
#define CC  CC1 CC2
Ivan Mahonin a5e8d6
#define CXL CO1B CO4B "q -5 0 -8 -5 q 3 5 8 5 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define Cb0 "l -4 10 " Co3 Co4 Co1
Ivan Mahonin a5e8d6
#define Cb  Cb0 Co2 Co3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CUP "l 10 -25 "
Ivan Mahonin a5e8d6
#define CDN "l -10 25 "
Ivan Mahonin a5e8d6
#define CUP2 "l 20 -50 "
Ivan Mahonin a5e8d6
#define CDN2 "l -20 50 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CEE "m -18 -65 l 2 -2 m 10 0 l -2 2 m 8 65 "
Ivan Mahonin a5e8d6
#define CYY "m -28 -65 q 3 5 17 -5 m 11 70 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define CDot   "m 2 0 q 0 2 -2 2 q -2 0 -2 -2 q 0 -2 2 -2 q 2 0 2 2 "
Ivan Mahonin a5e8d6
#define CComma CDot "q -1 5 -8 10 m 8 -10 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_O1 "q 20 -50 0 -50 "
Ivan Mahonin a5e8d6
#define C_O2 "q -20 0 -40 50 "
Ivan Mahonin a5e8d6
#define C_O3 "q -20 50 0 50 "
Ivan Mahonin a5e8d6
#define C_O4 "q 20 0 40 -50 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_O1B "q 20 0 0 50 "
Ivan Mahonin a5e8d6
#define C_O2B "q 20 -50 40 -50 "
Ivan Mahonin a5e8d6
#define C_O3B "q -20 0 0 -50 "
Ivan Mahonin a5e8d6
#define C_O4B "q -20 50 -40 50 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_XL1 "m 36 -90 q 10 -10 18 -10 "
Ivan Mahonin a5e8d6
#define C_XL2 C_O1B C_O4B
Ivan Mahonin a5e8d6
#define C_XL3 "q -7.5 0 -14 -10 q 3.5 10 14 10 "
Ivan Mahonin a5e8d6
#define C_XL  C_XL1 C_XL2 C_XL3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_XR1 "q 7.5 0 14 10 "
Ivan Mahonin a5e8d6
#define C_XR2 "q -3.5 -10 -14 -10 "
Ivan Mahonin a5e8d6
#define C_XR3 C_O2 C_O3
Ivan Mahonin a5e8d6
#define C_XR  C_XR1 C_XR2 C_XR3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_AL0 "m 4 -10 q 1 10 11 10 "
Ivan Mahonin a5e8d6
#define C_AL  C_AL0 "q 30 0 95 -100 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_LU  CLU
Ivan Mahonin a5e8d6
#define C_LD  CLD
Ivan Mahonin a5e8d6
#define C_LLD "q -10 25 0 25 q 15 0 70 -100 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_J1  "m 64 -85 l -24 60 "
Ivan Mahonin a5e8d6
#define C_J2  "l -4 10 q -6 15 -21 15 q -5 0 -11 -10 m 11 10 "
Ivan Mahonin a5e8d6
#define C_JJ2 "l -4 10 q -6 15 -21 15 q -5 0 -11 -10 q 1 10 11 10 "
Ivan Mahonin a5e8d6
#define C_J   C_J1 C_J2
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_T "m 28 -70 c -10 -10 -8 -30 12 -30 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_E "m 69 -90 " C_XR2 "q -15 0 -23 20 q -3 25 15 25 q -25 0 -35 25 q -12 30 13 30 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_3 C_XL1 "q 15 0 7 20 q -10 25 -25 25 q 15 0 5 25 q -12 30 -32 30 " C_XL3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_B1  "m 60 -100 " CDN CDN2 CQD2 "q 56 -90 71 -90 "
Ivan Mahonin a5e8d6
#define C_B2  "q 15 0 7 20 q -10 25 -30 25 "
Ivan Mahonin a5e8d6
#define C_B3  "q 25 0 15 25 q -12 30 -32 30 q -5 0 -8 -5 q 3 5 8 5 "
Ivan Mahonin a5e8d6
#define C_B   C_B1 C_B2 C_B3
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define C_EE "m 31 -115 l 2 -2 m 10 0 l -2 2 m -41 115 "
Ivan Mahonin a5e8d6
#define C_YY "m -26.5 -15 q 3 5 17 -5 m 9.5 20 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define LLBO MUP "q 25 -25 35 -25 "
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define LBL { MUP CLU }
Ivan Mahonin a5e8d6
#define LBO { "m 35 -50 ", LLBO }
Ivan Mahonin a5e8d6
#define LBA { "m 40 -25 ", LLBO CO1B }
Ivan Mahonin a5e8d6
#define LBQ { MUP CQU }
Ivan Mahonin a5e8d6
#define LBE { MUPE "c 46 -23 56 -40 41 -40 " }
Ivan Mahonin a5e8d6
#define LBN { "m 20 -50 " CDN, MUP "l 25 -25 " CDN }
Ivan Mahonin a5e8d6
#define LBX { "m 18 -45 q 7 -5 12 -5 ", LLBO }
Ivan Mahonin a5e8d6
#define LBC { "m 38 -45 ", LLBO CC1 }
Ivan Mahonin a5e8d6
#define LBJ { MUP CJL }
Ivan Mahonin a5e8d6
#define LBr { MUP "l 25 -25 q 5 25 30 0 " }
Ivan Mahonin a5e8d6
#define LBR { MUP CJR }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define LEL { CLD MDN, NULL, "c -14 35 4 25 24 15 " MDNE }
Ivan Mahonin a5e8d6
#define LELY { CLD MDN CYY, NULL, "c -14 35 4 25 24 15 " MDNE CYY }
Ivan Mahonin a5e8d6
#define LEO { "m 15 0 ", "q 15 0 40 -25 " MDN, "q 19 0 39 -10 " MDNE }
Ivan Mahonin a5e8d6
#define LEE { "q 19 0 39 -10 " MDNE, "q 15 0 40 -25 " MDN }
Ivan Mahonin a5e8d6
#define LEEE { "q 19 0 39 -10 " MDNE CEE, "q 15 0 40 -25 " MDN CEE }
Ivan Mahonin a5e8d6
#define LEQ { CQD2 CQD3 MDN, NULL, CQD2 CQD3E MDNE }
Ivan Mahonin a5e8d6
#define LEX { "q 15 0 40 -25 " MDN, NULL, "q 19 0 39 -10 " MDNE }
Ivan Mahonin a5e8d6
#define LEK { CKD2 MDN, NULL, "c -12 30 2 20 22 10 " MDNE }
Ivan Mahonin a5e8d6
#define LEG { CGD MDN, NULL, CGDE MDNE }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define L_EO1 { "m 30 0 ", "q 15 0 40 -25 " MDN, "q 19 0 39 -10 " MDNE }
Ivan Mahonin a5e8d6
#define L_EO2 { "m 60 0 ", "q 15 0 40 -25 " MDN, "q 19 0 39 -10 " MDNE }
Ivan Mahonin a5e8d6
#define L_EO3 { "m 75 0 ", "q 15 0 40 -25 " MDN, "q 19 0 39 -10 " MDNE }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
#define L_EA { "q 20 -50 -10 -50 c -20 0 -16 40 14 40 q 21 0 36 -15 " MDN, NULL, \
Ivan Mahonin a5e8d6
               "q 20 -50 -10 -50 c -20 0 -18 45 12 45 q 22 0 32 -5 " MDNE }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
typedef struct {
Ivan Mahonin a5e8d6
  const char *base;
Ivan Mahonin a5e8d6
  const char *link0;
Ivan Mahonin a5e8d6
  const char *link1;
Ivan Mahonin a5e8d6
} Link;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
typedef struct {
Ivan Mahonin a5e8d6
  const char *name;
Ivan Mahonin a5e8d6
  Link begin;
Ivan Mahonin a5e8d6
  const char *mid;
Ivan Mahonin a5e8d6
  Link end;
Ivan Mahonin a5e8d6
  int linkMode;
Ivan Mahonin a5e8d6
  const char *alias;
Ivan Mahonin a5e8d6
} Letter;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Letter letters[] = {
Ivan Mahonin a5e8d6
  { "а", LBA, CFO1 CUP CDN, LEL },
Ivan Mahonin a5e8d6
  { "б", LBA, CFO1 CUP2 "q 10 -25 25 -25 l 15 0 m -85 100", LEO },
Ivan Mahonin a5e8d6
  { "в", LBQ, CFO3 CO3, LEO },
Ivan Mahonin a5e8d6
  { "г", LBL, "", LEL },
Ivan Mahonin a5e8d6
  { "д", LBA, CFO1 CUP CDN CQD1, LEQ },
Ivan Mahonin a5e8d6
  { "е", LBE, CO2 CO3, LEE, 1 },
Ivan Mahonin a5e8d6
  { "ё", LBE, CO2 CO3, LEEE, 1 },
Ivan Mahonin a5e8d6
  { "ж", LBX, CXL "q 15 0 55 -50 " CDN2 "q 40 -50 55 -50 " CC, LEX },
Ivan Mahonin a5e8d6
  { "з", LBX, CO1B "q -3 7.5 -19 15 q 18 -7.5 1 35 ", LEQ },
Ivan Mahonin a5e8d6
  { "и", LBN, CLLD CDN, LEL },
Ivan Mahonin a5e8d6
  { "й", LBN, CLLD CDN, LELY },
Ivan Mahonin a5e8d6
  { "к", LBN, CDN "q 48 -70 46 -40 m -46 40 " CKD1, LEK },
Ivan Mahonin a5e8d6
  { "л", LBJ, CDN, LEL },
Ivan Mahonin a5e8d6
  { "м", LBJ, CDN CLLD CDN, LEL },
Ivan Mahonin a5e8d6
  { "н", LBN, CDN CUP "q 30 0 40 -25" CDN, LEL },
Ivan Mahonin a5e8d6
  { "о", LBO, CFO2 CO2 CO3, LEO },
Ivan Mahonin a5e8d6
  { "п", LBN, CDN CUP CLU, LEL },
Ivan Mahonin a5e8d6
  { "р", LBN, "l -30 75 l 30 -75 " CLU, LEL },
Ivan Mahonin a5e8d6
  { "с", LBC, CC2, LEX },
Ivan Mahonin a5e8d6
  { "т", LBN, CDN CUP CLU CDN CUP CLU, LEL },
Ivan Mahonin a5e8d6
  { "у", LBN, CLLD CDN CQD1, LEQ },
Ivan Mahonin a5e8d6
  { "ф", LBA, CFO1 CUP CDN CFO3 "l -30 75 m 35 -50 ", LEO },
Ivan Mahonin a5e8d6
  { "х", LBX, CXL CO4 CO2B CC, LEX },
Ivan Mahonin a5e8d6
  { "ц", LBN, CLLD CDN, LEG },
Ivan Mahonin a5e8d6
  { "ч", LBr, CDN, LEL },
Ivan Mahonin a5e8d6
  { "ш", LBN, CLLD CDN CLLD CDN, LEL },
Ivan Mahonin a5e8d6
  { "щ", LBN, CLLD CDN CLLD CDN, LEG },
Ivan Mahonin a5e8d6
  { "ъ", LBr, CDN Cb, LEO },
Ivan Mahonin a5e8d6
  { "ы", LBN, Cb0 "q 20 0 28 -20 " CDN, LEL },
Ivan Mahonin a5e8d6
  { "ь", LBN, Cb, LEO },
Ivan Mahonin a5e8d6
  { "э", LBX, CXL "m 10 -25 l 15 0 m -25 25 ", LEO },
Ivan Mahonin a5e8d6
  { "ю", LBN, CDN CUP "c 30 0 40 -25 55 -25 " CFO2 CO2 CO3, LEO },
Ivan Mahonin a5e8d6
  { "я", LBR, CDN, LEL },
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  //{ "А", {""}, C_AL "m -64 60 l 50 0 m 14 -60 " CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "А", {""}, C_AL CDN2 CDN2, L_EA, 3 },
Ivan Mahonin a5e8d6
  { "Б", {""}, "m 53 -85 l -24 60 " CQD2 "q 33 -45 48 -45 " C_B3 "m -30 0 " C_T "l 50 0 m -60 100 ", L_EO2, 3 },
Ivan Mahonin a5e8d6
  { "В", {""}, C_B, L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "Г", {""}, C_J "m -10 0 " C_T "l 60 0 m -90 100 ", L_EO3, 3 },
Ivan Mahonin a5e8d6
  { "Д", {""}, C_J1 CO4B "c -15 0 -9 -15 1 -15 c 10 0 14 15 24 15 " C_O4 "q 20 -50 -15 -50 q -25 0 -37 30 m 12 70 ", L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "Е", {""}, C_E, LEX, 3 },
Ivan Mahonin a5e8d6
  { "Ё", {""}, C_E C_EE, LEX, 3 },
Ivan Mahonin a5e8d6
  { "Ж", {""}, C_XL "q 30 0 85 -100 " CDN2 CDN2 "q 55 -100 85 -100 " C_XR, LEX, 3 },
Ivan Mahonin a5e8d6
  { "З", {""}, C_3, L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "И", {""}, MUP3 C_LU CDN2 C_LLD CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "Й", {""}, MUP3 C_LU CDN2 C_LLD C_YY CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "К", {""}, "m 40 -75 l 25 -25 " CDN CDN2 CQD2 "c 4 -10 76 -90 86 -90 q 2.5 0 1 10 m -56 55 " CO2B CO1B "l -4 10 ", LEL, 3 },
Ivan Mahonin a5e8d6
  { "Л", {""}, C_AL CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "М", {""}, C_AL CDN2 CDN C_LLD CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "Н", {""}, "m 40 -75 l 25 -25 " CDN CDN2 CQD2 "c 8 -20 96 -60 102 -80 " CQU2, LEL, 3 },
Ivan Mahonin a5e8d6
  { "О", {""}, "m 20 0 " C_O4 C_O1 C_O2 C_O3, L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "П", {""}, C_J "m -5 0 " C_T "l 60 0 m -90 100 " C_J1, LEL, 3 },
Ivan Mahonin a5e8d6
  { "Р", {""}, C_J "m 18 -70 c -5 -5 7 -30 32 -30 c 35 0 25 30 15 35 m -65 65 ", L_EO2, 3 },
Ivan Mahonin a5e8d6
  { "С", {""}, "m 74 -90 " C_XR2 C_XR3, LEX, 3 },
Ivan Mahonin a5e8d6
  { "Т", {""}, C_J "m -5 0 " C_T "l 80 0 m -110 100 " C_J1 CDN "m -10 0 " C_J1, LEL, 3 },
Ivan Mahonin a5e8d6
  { "У", {""}, MUP3 C_LU CLLD CDN2 CDN C_JJ2, LEO, 3 },
Ivan Mahonin a5e8d6
  { "Ф", {""}, "m 60 -75 " CFO1 CUP CDN CFO3 CDN2 C_J2, L_EO2, 3 },
Ivan Mahonin a5e8d6
  { "Х", {""}, C_XL C_O4 C_O2B C_XR, LEX, 3 },
Ivan Mahonin a5e8d6
  { "Ц", {""}, MUP3 C_LU CDN2 C_LLD CDN2 CDN, LEG, 3 },
Ivan Mahonin a5e8d6
  { "Ч", {""}, MUP3 C_LU CLLD CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "Ш", {""}, MUP3 C_LU CDN2 C_LLD CDN2 CDN C_LLD CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
  { "Щ", {""}, MUP3 C_LU CDN2 C_LLD CDN2 CDN C_LLD CDN2 CDN, LEG, 3 },
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  { "Э", {""}, C_XL "m 20 -50 l 20 0 m -40 50 ", L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "Ю", {""}, "m 40 -75 l 25 -25 " CDN CDN2 CQD2 "c 8 -20 46 -35 56 -40 " C_O3 C_O4 C_O1 C_O2 C_O3, L_EO1, 3 },
Ivan Mahonin a5e8d6
  { "Я", {""}, C_AL0 "c 15 0 55 -50 65 -75 " CFO1 CUP CDN2 CDN, LEL, 3 },
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  { "-", {""}, MDOTSP "m 10 -25 l 40 0 m -10 25 " MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { ".", {""}, MDOTSP CDot MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { ",", {""}, MDOTSP CComma MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { "\"",{""}, "m 40 -100 " CComma "m 10 0 " CComma "m -40 100 " MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { "»", {}, NULL, {}, 0, "\"" },
Ivan Mahonin a5e8d6
  { "“", {}, NULL, {}, 0, "\"" },
Ivan Mahonin a5e8d6
  { "«", {""}, MDOTSP CComma "m 10 0 " CComma MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { "„", {}, NULL, {}, 0, "«" },
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  { "!", {""}, MDOTSP "m 40 -100 l -34 85 m -6 15 " CDot MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
  { "?", {""}, MDOTSP "m 15 -75 " CO2B CO1B "c -10 25 -29 35 -39 60 m -6 15 " CDot MDOTSP, {""}, 2 },
Ivan Mahonin a5e8d6
};
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
char path[1024*1024];
Ivan Mahonin a5e8d6
double pathX0 = 60, pathRowStep = 175, pathWidth = 5;
Ivan Mahonin a5e8d6
char *pathEnd;
Ivan Mahonin a5e8d6
double pathX, pathY;
Ivan Mahonin a5e8d6
FILE *pathFile;
Ivan Mahonin a5e8d6
int pathMode;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
void putPath(const char *str) {
Ivan Mahonin a5e8d6
  if (!str || !*str) return;
Ivan Mahonin a5e8d6
  if (!*path) {
Ivan Mahonin a5e8d6
    char buf[256] = {};
Ivan Mahonin a5e8d6
    sprintf(buf, "M %g %g ", pathX, pathY);
Ivan Mahonin a5e8d6
    char *c = buf;
Ivan Mahonin a5e8d6
    while(*c) *pathEnd++ = *c++;
Ivan Mahonin a5e8d6
  }
Ivan Mahonin a5e8d6
  spTrack(str, &pathX, &pathY);
Ivan Mahonin a5e8d6
  while(*str) *pathEnd++ = *str++;
Ivan Mahonin a5e8d6
  *pathEnd = 0;
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
void splitPath(int mode) {
Ivan Mahonin a5e8d6
  if (mode >= 2) {
Ivan Mahonin a5e8d6
    if (pathMode >= 2) {
Ivan Mahonin a5e8d6
      if (*path) svgAddPath(pathFile, path, pathWidth, TRUE);
Ivan Mahonin a5e8d6
      *(pathEnd = path) = 0;
Ivan Mahonin a5e8d6
    }
Ivan Mahonin a5e8d6
  } else
Ivan Mahonin a5e8d6
  if (mode >= 1) {
Ivan Mahonin a5e8d6
    pathX = pathX0;
Ivan Mahonin a5e8d6
    pathY += pathRowStep;
Ivan Mahonin a5e8d6
    if (pathMode >= 1) {
Ivan Mahonin a5e8d6
      if (*path) svgAddPath(pathFile, path, pathWidth, TRUE);
Ivan Mahonin a5e8d6
      *(pathEnd = path) = 0;
Ivan Mahonin a5e8d6
    } else
Ivan Mahonin a5e8d6
    if (*path) {
Ivan Mahonin a5e8d6
      char buf[256] = {};
Ivan Mahonin a5e8d6
      sprintf(buf, "M %g %g ", pathX, pathY);
Ivan Mahonin a5e8d6
      putPath(buf);
Ivan Mahonin a5e8d6
    }
Ivan Mahonin a5e8d6
  } else {
Ivan Mahonin a5e8d6
    if (*path) svgAddPath(pathFile, path, pathWidth, TRUE);
Ivan Mahonin a5e8d6
    //*(pathEnd = path) = 0;
Ivan Mahonin a5e8d6
  }
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
void textToPath(const char *text) {
Ivan Mahonin a5e8d6
  pathEnd = path;
Ivan Mahonin a5e8d6
  *pathEnd = 0;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  int cnt = sizeof(letters)/sizeof(*letters);
Ivan Mahonin a5e8d6
  Letter *prev = NULL;
Ivan Mahonin a5e8d6
  while(*text) {
Ivan Mahonin a5e8d6
    Letter *curr = NULL;
Ivan Mahonin a5e8d6
    do {
Ivan Mahonin a5e8d6
      for(int i = 0; i < cnt; ++i) {
Ivan Mahonin a5e8d6
        Letter *l = &letters[i];
Ivan Mahonin a5e8d6
        const char *t = curr ? curr->alias : text;
Ivan Mahonin a5e8d6
        const char *ln = l->name;
Ivan Mahonin a5e8d6
        while(*t && *ln && *t == *ln) ++t, ++ln;
Ivan Mahonin a5e8d6
        if (!*ln) {
Ivan Mahonin a5e8d6
          if (!curr) text = t;
Ivan Mahonin a5e8d6
          curr = l;
Ivan Mahonin a5e8d6
          break;
Ivan Mahonin a5e8d6
        }
Ivan Mahonin a5e8d6
      }
Ivan Mahonin a5e8d6
    } while(curr && curr->alias);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
    if (prev) {
Ivan Mahonin a5e8d6
      const char *link = curr && curr->linkMode == 1 ? prev->end.link1 : prev->end.link0;
Ivan Mahonin a5e8d6
      putPath(curr && curr->linkMode != 2 && curr->linkMode != 3 && link ? link : prev->end.base);
Ivan Mahonin a5e8d6
    }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
    splitPath(2);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
    if (curr) {
Ivan Mahonin a5e8d6
      const char *link = curr->linkMode == 1 ? curr->begin.link1 : curr->begin.link0;
Ivan Mahonin a5e8d6
      putPath(prev && prev->linkMode != 2 && link ? link : curr->begin.base);
Ivan Mahonin a5e8d6
      putPath(curr->mid);
Ivan Mahonin a5e8d6
    } else
Ivan Mahonin a5e8d6
    if (*text == '\n') {
Ivan Mahonin a5e8d6
      splitPath(1);
Ivan Mahonin a5e8d6
      ++text;
Ivan Mahonin a5e8d6
    } else {
Ivan Mahonin a5e8d6
      putPath(MSPACE);
Ivan Mahonin a5e8d6
      ++text;
Ivan Mahonin a5e8d6
    }
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
    prev = curr;
Ivan Mahonin a5e8d6
  }
Ivan Mahonin a5e8d6
  if (prev) putPath(prev->end.base);
Ivan Mahonin a5e8d6
  splitPath(0);
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
int textFileToSVG(const char *textfile, const char *svgfile) {
Ivan Mahonin a5e8d6
  FILE *sf = fopen(textfile, "r");
Ivan Mahonin a5e8d6
  if (!sf) return FALSE;
Ivan Mahonin a5e8d6
  char buf[1024*1024] = {};
Ivan Mahonin a5e8d6
  char *str = buf;
Ivan Mahonin a5e8d6
  while(TRUE) {
Ivan Mahonin a5e8d6
    int c = fgetc(sf);
Ivan Mahonin a5e8d6
    if (c <= 0) break;
Ivan Mahonin a5e8d6
    *str++ = c;
Ivan Mahonin a5e8d6
  }
Ivan Mahonin a5e8d6
  fclose(sf);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  pathX = pathX0;
Ivan Mahonin a5e8d6
  pathY = pathRowStep;
Ivan Mahonin a5e8d6
  pathEnd = path;
Ivan Mahonin a5e8d6
  pathFile = svgBegin(svgfile, 300, 300, 10);
Ivan Mahonin a5e8d6
  if (!pathFile) return FALSE;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  textToPath(buf);
Ivan Mahonin a5e8d6
  svgEnd(pathFile);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  pathX = pathX0;
Ivan Mahonin a5e8d6
  pathY = pathRowStep;
Ivan Mahonin a5e8d6
  pathEnd = path;
Ivan Mahonin a5e8d6
  pathFile = NULL;
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  return TRUE;
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
void init() {
Ivan Mahonin a5e8d6
  pathMode = 2;
Ivan Mahonin a5e8d6
  pathRowStep = 200;
Ivan Mahonin a5e8d6
  textFileToSVG("data/writing.txt", "data/output/writing.svg");
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  pathRowStep = 175;
Ivan Mahonin a5e8d6
  pathMode = 0;
Ivan Mahonin a5e8d6
  pathX = pathX0;
Ivan Mahonin a5e8d6
  pathY = pathRowStep;
Ivan Mahonin a5e8d6
  pathEnd = path;
Ivan Mahonin a5e8d6
  pathFile = svgBegin("data/output/generated-writing.svg", 300, 300, 10);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  textToPath(
Ivan Mahonin a5e8d6
    "ааа ббб ввв ггг ддд еее ёёё\n"
Ivan Mahonin a5e8d6
    "жжж ззз иии ййй ккк ллл ммм\n"
Ivan Mahonin a5e8d6
    "ннн ооо ппп ррр ссс ттт ууу\n"
Ivan Mahonin a5e8d6
    "ффф ххх ццц ччч шшш щщщ ъъъ\n"
Ivan Mahonin a5e8d6
    "ыыы ььь эээ ююю яяя\n"
Ivan Mahonin a5e8d6
    "ае бе де ке хе це ье еа\n"
Ivan Mahonin a5e8d6
    "ААа ББб ВВв ГГг ДДд ЕЕе\n"
Ivan Mahonin a5e8d6
    "ЁЁё ЖЖж ЗЗз ИИи ЙЙй ККк\n"
Ivan Mahonin a5e8d6
    "ЛЛл ММм ННн ООо ППп РРр\n"
Ivan Mahonin a5e8d6
    "ССс ТТт УУу ФФф ХХх ЦЦц\n"
Ivan Mahonin a5e8d6
    "ЧЧч ШШш ЩЩщ ЪЪъ ЫЫы ЬЬь\n"
Ivan Mahonin a5e8d6
    "ЭЭэ ЮЮю ЯЯя\n"
Ivan Mahonin a5e8d6
    "Ае, Бе. Ге? Же! «Ие - Ке» \"Це\" „Ье“ т-т\n" );
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  svgEnd(pathFile);
Ivan Mahonin a5e8d6
  pathFile = NULL;
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
void draw() {
Ivan Mahonin a5e8d6
  saveState();
Ivan Mahonin a5e8d6
  zoom(0.4);
Ivan Mahonin a5e8d6
  //translate(150, 150);
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  stroke(COLOR_BLACK);
Ivan Mahonin a5e8d6
  strokeWidth(5);
Ivan Mahonin a5e8d6
  noFill();
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
  spMoveTo(0, 0);
Ivan Mahonin a5e8d6
  spParse(path);
Ivan Mahonin a5e8d6
  restoreState();
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
Ivan Mahonin a5e8d6
int main() {
Ivan Mahonin a5e8d6
  windowSetVariableFrameRate();
Ivan Mahonin a5e8d6
  windowSetResizable(TRUE);
Ivan Mahonin a5e8d6
  windowSetSize(1250, 800);
Ivan Mahonin a5e8d6
  windowSetInit(&init);
Ivan Mahonin a5e8d6
  windowSetDraw(&draw);
Ivan Mahonin a5e8d6
  windowRun();
Ivan Mahonin a5e8d6
  return 0;
Ivan Mahonin a5e8d6
}
Ivan Mahonin a5e8d6