curvedraw
changeset 8:8bf96e11ed1f
curves file format parsing (untested)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 19 Dec 2015 08:00:09 +0200 |
parents | 6e980fddbf3b |
children | c2008ba88d03 |
files | src/curvefile.cc |
diffstat | 1 files changed, 134 insertions(+), 3 deletions(-) [+] |
line diff
1.1 --- a/src/curvefile.cc Fri Dec 18 07:07:19 2015 +0200 1.2 +++ b/src/curvefile.cc Sat Dec 19 08:00:09 2015 +0200 1.3 @@ -1,4 +1,6 @@ 1.4 #include <stdlib.h> 1.5 +#include <ctype.h> 1.6 +#include <string> 1.7 #include "curvefile.h" 1.8 1.9 static bool save_curve(FILE *fp, const Curve *curve); 1.10 @@ -15,7 +17,7 @@ 1.11 1.12 bool save_curves(FILE *fp, const Curve * const *curves, int count) 1.13 { 1.14 - fprintf(stderr, "GCURVES\ncount %d\n", count); 1.15 + fprintf(stderr, "GCURVES\n"); 1.16 1.17 for(int i=0; i<count; i++) { 1.18 if(!save_curve(fp, curves[i])) { 1.19 @@ -53,7 +55,7 @@ 1.20 1.21 Curve **load_curves(const char *fname, int *countret) 1.22 { 1.23 - FILE *fp = fopen(fname, "rb"); 1.24 + FILE *fp = fopen(fname, "r"); 1.25 if(!fp) return false; 1.26 1.27 Curve **res = load_curves(fp, countret); 1.28 @@ -61,8 +63,137 @@ 1.29 return res; 1.30 } 1.31 1.32 +static std::string next_token(FILE *fp) 1.33 +{ 1.34 + std::string s; 1.35 + int c; 1.36 + while((c = fgetc(fp)) != -1 && isspace(c)); // skip whitespace 1.37 + if(feof(fp)) return s; 1.38 + while((c = fgetc(fp)) != -1 && !isspace(c)) { 1.39 + s.push_back(c); 1.40 + } 1.41 + return s; 1.42 +} 1.43 + 1.44 +static bool expect_str(FILE *fp, const char *s) 1.45 +{ 1.46 + std::string tok = next_token(fp); 1.47 + if(tok != std::string(s)) { 1.48 + if(!(tok.empty() && feof(fp))) { 1.49 + fprintf(stderr, "expected: %s\n", s); 1.50 + } 1.51 + return false; 1.52 + } 1.53 + return true; 1.54 +} 1.55 + 1.56 +static bool expect_float(FILE *fp, float *ret) 1.57 +{ 1.58 + std::string tok = next_token(fp); 1.59 + const char *cs = tok.c_str(); 1.60 + char *endp; 1.61 + *ret = strtod(cs, &endp); 1.62 + if(endp != cs + tok.length()) { 1.63 + if(!(tok.empty() && feof(fp))) { 1.64 + fprintf(stderr, "number expected\n"); 1.65 + } 1.66 + return false; 1.67 + } 1.68 + return true; 1.69 +} 1.70 + 1.71 +static bool expect_int(FILE *fp, int *ret) 1.72 +{ 1.73 + std::string tok = next_token(fp); 1.74 + const char *cs = tok.c_str(); 1.75 + char *endp; 1.76 + *ret = strtol(cs, &endp, 0); 1.77 + if(endp != cs + tok.length()) { 1.78 + if(!(tok.empty() && feof(fp))) { 1.79 + fprintf(stderr, "integer expected\n"); 1.80 + } 1.81 + return false; 1.82 + } 1.83 + return true; 1.84 +} 1.85 + 1.86 +static Curve *curve_block(FILE *fp) 1.87 +{ 1.88 + if(!expect_str(fp, "curve") || !expect_str(fp, "{")) { 1.89 + return 0; 1.90 + } 1.91 + 1.92 + Curve *curve = new Curve; 1.93 + int cpcount = -1; 1.94 + std::string tok; 1.95 + while(!(tok = next_token(fp)).empty() && tok != "}") { 1.96 + if(tok == "cpcount") { 1.97 + if(cpcount != -1 || !expect_int(fp, &cpcount) || cpcount <= 0) { 1.98 + goto err; 1.99 + } 1.100 + } else if(tok == "type") { 1.101 + tok = next_token(fp); 1.102 + if(tok == "polyline") { 1.103 + curve->set_type(CURVE_LINEAR); 1.104 + } else if(tok == "hermite") { 1.105 + curve->set_type(CURVE_HERMITE); 1.106 + } else if(tok == "bspline") { 1.107 + curve->set_type(CURVE_BSPLINE); 1.108 + } else { 1.109 + goto err; 1.110 + } 1.111 + } else { 1.112 + if(!expect_str(fp, "cp")) { 1.113 + goto err; 1.114 + } 1.115 + Vector3 cp; 1.116 + for(int i=0; i<3; i++) { 1.117 + if(!expect_float(fp, &cp[i])) { 1.118 + goto err; 1.119 + } 1.120 + } 1.121 + curve->add_point(Vector2(cp.x, cp.y), cp.z); 1.122 + } 1.123 + } 1.124 + 1.125 + if(curve->size() != cpcount) { 1.126 + fprintf(stderr, "warning: curve cpcount was %d, but read %d control points\n", cpcount, curve->size()); 1.127 + } 1.128 + 1.129 + return curve; 1.130 +err: 1.131 + fprintf(stderr, "failed to parse curve block\n"); 1.132 + delete curve; 1.133 + return 0; 1.134 +} 1.135 + 1.136 Curve **load_curves(FILE *fp, int *countret) 1.137 { 1.138 - return 0; // TODO 1.139 + if(!expect_str(fp, "GCURVES")) { 1.140 + fprintf(stderr, "load_curves: failed to load, invalid file format\n"); 1.141 + return 0; 1.142 + } 1.143 + 1.144 + std::vector<Curve*> curves; 1.145 + Curve *curve; 1.146 + 1.147 + while((curve = curve_block(fp))) { 1.148 + curves.push_back(curve); 1.149 + } 1.150 + 1.151 + int ncurves = (int)curves.size(); 1.152 + if(!feof(fp)) { 1.153 + for(int i=0; i<ncurves; i++) { 1.154 + delete curves[i]; 1.155 + } 1.156 + return 0; 1.157 + } 1.158 + 1.159 + Curve **carr = new Curve*[ncurves]; 1.160 + for(int i=0; i<ncurves; i++) { 1.161 + carr[i] = curves[i]; 1.162 + } 1.163 + *countret = ncurves; 1.164 + return carr; 1.165 } 1.166