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