Chlumsky 1 год назад
Родитель
Сommit
49453c96f1
4 измененных файлов с 72 добавлено и 58 удалено
  1. 2 2
      core/Vector2.hpp
  2. 18 5
      core/shape-description.cpp
  3. 19 31
      ext/import-svg.cpp
  4. 33 20
      main.cpp

+ 2 - 2
core/Vector2.hpp

@@ -24,8 +24,8 @@ struct Vector2 {
     }
 
     /// Sets individual elements of the vector.
-    inline void set(double x, double y) {
-        this->x = x, this->y = y;
+    inline void set(double newX, double newY) {
+        x = newX, y = newY;
     }
 
     /// Returns the vector's squared length.

+ 18 - 5
core/shape-description.cpp

@@ -2,6 +2,8 @@
 #define _CRT_SECURE_NO_WARNINGS
 #include "shape-description.h"
 
+#include <cstdlib>
+
 namespace msdfgen {
 
 int readCharF(FILE *input) {
@@ -25,14 +27,25 @@ int readCharS(const char **input) {
 }
 
 int readCoordF(FILE *input, Point2 &coord) {
-    return fscanf(input, "%lf,%lf", &coord.x, &coord.y);
+    return fscanf(input, "%lf , %lf", &coord.x, &coord.y);
 }
 
 int readCoordS(const char **input, Point2 &coord) {
-    int read = 0;
-    int result = sscanf(*input, "%lf,%lf%n", &coord.x, &coord.y, &read);
-    *input += read;
-    return result;
+    char *end = NULL;
+    coord.x = strtod(*input, &end);
+    if (end <= *input)
+        return 0;
+    *input = end;
+    while (**input == ' ' || **input == '\t' || **input == '\n' || **input == '\r')
+        ++*input;
+    if (**input != ',')
+        return 1;
+    ++*input;
+    coord.y = strtod(*input, &end);
+    if (end <= *input)
+        return 1;
+    *input = end;
+    return 2;
 }
 
 static bool writeCoord(FILE *output, Point2 coord) {

+ 19 - 31
ext/import-svg.cpp

@@ -52,37 +52,27 @@ static bool readNodeType(char &output, const char *&pathDef) {
     return false;
 }
 
-static bool readCoord(Point2 &output, const char *&pathDef) {
-    skipExtraChars(pathDef);
-    int shift;
-    double x, y;
-    if (sscanf(pathDef, "%lf%lf%n", &x, &y, &shift) == 2 || sscanf(pathDef, "%lf , %lf%n", &x, &y, &shift) == 2) {
-        output.x = x;
-        output.y = y;
-        pathDef += shift;
+static bool readDouble(double &output, const char *&pathDef) {
+    char *end = NULL;
+    output = strtod(pathDef, &end);
+    if (end > pathDef) {
+        pathDef = end;
         return true;
     }
     return false;
 }
 
-static bool readDouble(double &output, const char *&pathDef) {
+static bool readCoord(Point2 &output, const char *&pathDef) {
     skipExtraChars(pathDef);
-    int shift;
-    double v;
-    if (sscanf(pathDef, "%lf%n", &v, &shift) == 1) {
-        pathDef += shift;
-        output = v;
-        return true;
-    }
-    return false;
+    return readDouble(output.x, pathDef) && (skipExtraChars(pathDef), readDouble(output.y, pathDef));
 }
 
 static bool readBool(bool &output, const char *&pathDef) {
     skipExtraChars(pathDef);
-    int shift;
-    int v;
-    if (sscanf(pathDef, "%d%n", &v, &shift) == 1) {
-        pathDef += shift;
+    char *end = NULL;
+    long v = strtol(pathDef, &end, 10);
+    if (end > pathDef) {
+        pathDef = end;
         output = v != 0;
         return true;
     }
@@ -339,10 +329,10 @@ bool loadSvgShape(Shape &output, const char *filename, int pathIndex, Vector2 *d
         return false;
 
     Vector2 dims(root->DoubleAttribute("width"), root->DoubleAttribute("height"));
-    double left, top;
-    const char *viewBox = root->Attribute("viewBox");
-    if (viewBox)
-        sscanf(viewBox, "%lf %lf %lf %lf", &left, &top, &dims.x, &dims.y);
+    if (const char *viewBox = root->Attribute("viewBox")) {
+        double left = 0, top = 0;
+        readDouble(left, viewBox) && readDouble(top, viewBox) && readDouble(dims.x, viewBox) && readDouble(dims.y, viewBox);
+    }
     if (dimensions)
         *dimensions = dims;
     output.contours.clear();
@@ -372,9 +362,8 @@ int loadSvgShape(Shape &output, Shape::Bounds &viewBox, const char *filename) {
 
     viewBox.l = 0, viewBox.b = 0;
     Vector2 dims(root->DoubleAttribute("width"), root->DoubleAttribute("height"));
-    const char *viewBoxStr = root->Attribute("viewBox");
-    if (viewBoxStr)
-        sscanf(viewBoxStr, "%lf %lf %lf %lf", &viewBox.l, &viewBox.b, &dims.x, &dims.y);
+    if (const char *viewBoxStr = root->Attribute("viewBox"))
+        readDouble(viewBox.l, viewBoxStr) && readDouble(viewBox.b, viewBoxStr) && readDouble(dims.x, viewBoxStr) && readDouble(dims.y, viewBoxStr);
     viewBox.r = viewBox.l+dims.x;
     viewBox.t = viewBox.b+dims.y;
     output.contours.clear();
@@ -550,9 +539,8 @@ int loadSvgShape(Shape &output, Shape::Bounds &viewBox, const char *filename) {
 
     viewBox.l = 0, viewBox.b = 0;
     Vector2 dims(root->DoubleAttribute("width"), root->DoubleAttribute("height"));
-    const char *viewBoxStr = root->Attribute("viewBox");
-    if (viewBoxStr)
-        sscanf(viewBoxStr, "%lf %lf %lf %lf", &viewBox.l, &viewBox.b, &dims.x, &dims.y);
+    if (const char *viewBoxStr = root->Attribute("viewBox"))
+        readDouble(viewBox.l, viewBoxStr) && readDouble(viewBox.b, viewBoxStr) && readDouble(dims.x, viewBoxStr) && readDouble(dims.y, viewBoxStr);
     viewBox.r = viewBox.l+dims.x;
     viewBox.t = viewBox.b+dims.y;
     return flags;

+ 33 - 20
main.cpp

@@ -10,6 +10,7 @@
 
 #define _USE_MATH_DEFINES
 #define _CRT_SECURE_NO_WARNINGS
+#include <cstdlib>
 #include <cstdio>
 #include <cmath>
 #include <cstring>
@@ -56,36 +57,48 @@ static char toupper(char c) {
 }
 
 static bool parseUnsigned(unsigned &value, const char *arg) {
-    char c;
-    return sscanf(arg, "%u%c", &value, &c) == 1;
+    char *end = NULL;
+    value = (unsigned) strtoul(arg, &end, 10);
+    return end > arg && !*end;
 }
 
 static bool parseUnsignedDecOrHex(unsigned &value, const char *arg) {
+    char *end = NULL;
     if (arg[0] == '0' && (arg[1] == 'x' || arg[1] == 'X')) {
-        char c;
-        return sscanf(arg+2, "%x%c", &value, &c) == 1;
+        arg += 2;
+        value = (unsigned) strtoul(arg, &end, 16);
+    } else
+        value = (unsigned) strtoul(arg, &end, 10);
+    return end > arg && !*end;
     }
-    return parseUnsigned(value, arg);
-}
 
 static bool parseUnsignedLL(unsigned long long &value, const char *arg) {
-    char c;
-    return sscanf(arg, "%llu%c", &value, &c) == 1;
+    if (*arg >= '0' && *arg <= '9') {
+        value = 0;
+        do {
+            value = 10*value+(*arg++-'0');
+        } while (*arg >= '0' && *arg <= '9');
+        return !*arg;
+}
+    return false;
 }
 
 static bool parseDouble(double &value, const char *arg) {
-    char c;
-    return sscanf(arg, "%lf%c", &value, &c) == 1;
+    char *end = NULL;
+    value = strtod(arg, &end);
+    return end > arg && !*end;
 }
 
 static bool parseAngle(double &value, const char *arg) {
-    char c1, c2;
-    int result = sscanf(arg, "%lf%c%c", &value, &c1, &c2);
-    if (result == 1)
-        return true;
-    if (result == 2 && (c1 == 'd' || c1 == 'D')) {
+    char *end = NULL;
+    value = strtod(arg, &end);
+    if (end > arg) {
+        arg = end;
+        if (*arg == 'd' || *arg == 'D') {
+            ++arg;
         value *= M_PI/180;
-        return true;
+    }
+        return !*arg;
     }
     return false;
 }
@@ -159,11 +172,11 @@ static FontHandle *loadVarFont(FreetypeHandle *library, const char *filename) {
             while (*filename && *filename != '=')
                 buffer.push_back(*filename++);
             if (*filename == '=') {
-                double value = 0;
-                int skip = 0;
-                if (sscanf(++filename, "%lf%n", &value, &skip) == 1) {
+                char *end = NULL;
+                double value = strtod(++filename, &end);
+                if (end > filename) {
+                    filename = end;
                     setFontVariationAxis(library, font, buffer.c_str(), value);
-                    filename += skip;
                 }
             }
         } while (*filename++ == '&');