Prechádzať zdrojové kódy

Removed dynamic_cast

Chlumsky 2 rokov pred
rodič
commit
052f5fffd7

+ 6 - 9
core/Shape.cpp

@@ -40,15 +40,12 @@ bool Shape::validate() const {
 }
 
 static void deconvergeEdge(EdgeHolder &edgeHolder, int param) {
-    {
-        const QuadraticSegment *quadraticSegment = dynamic_cast<const QuadraticSegment *>(&*edgeHolder);
-        if (quadraticSegment)
-            edgeHolder = quadraticSegment->convertToCubic();
-    }
-    {
-        CubicSegment *cubicSegment = dynamic_cast<CubicSegment *>(&*edgeHolder);
-        if (cubicSegment)
-            cubicSegment->deconverge(param, MSDFGEN_DECONVERGENCE_FACTOR);
+    switch (edgeHolder->type()) {
+        case (int) QuadraticSegment::EDGE_TYPE:
+            edgeHolder = static_cast<const QuadraticSegment *>(&*edgeHolder)->convertToCubic();
+            // fallthrough
+        case (int) CubicSegment::EDGE_TYPE:
+            static_cast<CubicSegment *>(&*edgeHolder)->deconverge(param, MSDFGEN_DECONVERGENCE_FACTOR);
     }
 }
 

+ 24 - 0
core/edge-segments.cpp

@@ -68,6 +68,30 @@ CubicSegment * CubicSegment::clone() const {
     return new CubicSegment(p[0], p[1], p[2], p[3], color);
 }
 
+int LinearSegment::type() const {
+    return (int) EDGE_TYPE;
+}
+
+int QuadraticSegment::type() const {
+    return (int) EDGE_TYPE;
+}
+
+int CubicSegment::type() const {
+    return (int) EDGE_TYPE;
+}
+
+const Point2 * LinearSegment::controlPoints() const {
+    return p;
+}
+
+const Point2 * QuadraticSegment::controlPoints() const {
+    return p;
+}
+
+const Point2 * CubicSegment::controlPoints() const {
+    return p;
+}
+
 Point2 LinearSegment::point(double param) const {
     return mix(p[0], p[1], param);
 }

+ 22 - 0
core/edge-segments.h

@@ -21,6 +21,10 @@ public:
     virtual ~EdgeSegment() { }
     /// Creates a copy of the edge segment.
     virtual EdgeSegment * clone() const = 0;
+    /// Returns the numeric code of the edge segment's type.
+    virtual int type() const = 0;
+    /// Returns the array of control points.
+    virtual const Point2 * controlPoints() const = 0;
     /// Returns the point on the edge specified by the parameter (between 0 and 1).
     virtual Point2 point(double param) const = 0;
     /// Returns the direction the edge has at the point specified by the parameter.
@@ -51,10 +55,16 @@ public:
 class LinearSegment : public EdgeSegment {
 
 public:
+    enum EdgeType {
+        EDGE_TYPE = 1
+    };
+
     Point2 p[2];
 
     LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
     LinearSegment * clone() const;
+    int type() const;
+    const Point2 * controlPoints() const;
     Point2 point(double param) const;
     Vector2 direction(double param) const;
     Vector2 directionChange(double param) const;
@@ -74,10 +84,16 @@ public:
 class QuadraticSegment : public EdgeSegment {
 
 public:
+    enum EdgeType {
+        EDGE_TYPE = 2
+    };
+
     Point2 p[3];
 
     QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
     QuadraticSegment * clone() const;
+    int type() const;
+    const Point2 * controlPoints() const;
     Point2 point(double param) const;
     Vector2 direction(double param) const;
     Vector2 directionChange(double param) const;
@@ -99,10 +115,16 @@ public:
 class CubicSegment : public EdgeSegment {
 
 public:
+    enum EdgeType {
+        EDGE_TYPE = 3
+    };
+
     Point2 p[4];
 
     CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
     CubicSegment * clone() const;
+    int type() const;
+    const Point2 * controlPoints() const;
     Point2 point(double param) const;
     Vector2 direction(double param) const;
     Vector2 directionChange(double param) const;

+ 31 - 28
core/shape-description.cpp

@@ -244,34 +244,37 @@ bool writeShapeDescription(FILE *output, const Shape &shape) {
                         default:;
                     }
                 }
-                if (const LinearSegment *e = dynamic_cast<const LinearSegment *>(&**edge)) {
-                    fprintf(output, "\t");
-                    writeCoord(output, e->p[0]);
-                    fprintf(output, ";\n");
-                    if (colorCode)
-                        fprintf(output, "\t\t%c;\n", colorCode);
-                }
-                if (const QuadraticSegment *e = dynamic_cast<const QuadraticSegment *>(&**edge)) {
-                    fprintf(output, "\t");
-                    writeCoord(output, e->p[0]);
-                    fprintf(output, ";\n\t\t");
-                    if (colorCode)
-                        fprintf(output, "%c", colorCode);
-                    fprintf(output, "(");
-                    writeCoord(output, e->p[1]);
-                    fprintf(output, ");\n");
-                }
-                if (const CubicSegment *e = dynamic_cast<const CubicSegment *>(&**edge)) {
-                    fprintf(output, "\t");
-                    writeCoord(output, e->p[0]);
-                    fprintf(output, ";\n\t\t");
-                    if (colorCode)
-                        fprintf(output, "%c", colorCode);
-                    fprintf(output, "(");
-                    writeCoord(output, e->p[1]);
-                    fprintf(output, "; ");
-                    writeCoord(output, e->p[2]);
-                    fprintf(output, ");\n");
+                const Point2 *p = (*edge)->controlPoints();
+                switch ((*edge)->type()) {
+                    case (int) LinearSegment::EDGE_TYPE:
+                        fprintf(output, "\t");
+                        writeCoord(output, p[0]);
+                        fprintf(output, ";\n");
+                        if (colorCode)
+                            fprintf(output, "\t\t%c;\n", colorCode);
+                        break;
+                    case (int) QuadraticSegment::EDGE_TYPE:
+                        fprintf(output, "\t");
+                        writeCoord(output, p[0]);
+                        fprintf(output, ";\n\t\t");
+                        if (colorCode)
+                            fprintf(output, "%c", colorCode);
+                        fprintf(output, "(");
+                        writeCoord(output, p[1]);
+                        fprintf(output, ");\n");
+                        break;
+                    case (int) CubicSegment::EDGE_TYPE:
+                        fprintf(output, "\t");
+                        writeCoord(output, p[0]);
+                        fprintf(output, ";\n\t\t");
+                        if (colorCode)
+                            fprintf(output, "%c", colorCode);
+                        fprintf(output, "(");
+                        writeCoord(output, p[1]);
+                        fprintf(output, "; ");
+                        writeCoord(output, p[2]);
+                        fprintf(output, ");\n");
+                        break;
                 }
             }
             fprintf(output, "\t#\n");

+ 12 - 6
ext/resolve-shape-geometry.cpp

@@ -24,12 +24,18 @@ void shapeToSkiaPath(SkPath &skPath, const Shape &shape) {
         if (!contour->edges.empty()) {
             skPath.moveTo(pointToSkiaPoint(contour->edges.front()->point(0)));
             for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
-                if (const LinearSegment *linearSegment = dynamic_cast<const LinearSegment *>(&**edge))
-                    skPath.lineTo(pointToSkiaPoint(linearSegment->p[1]));
-                else if (const QuadraticSegment *quadraticSegment = dynamic_cast<const QuadraticSegment *>(&**edge))
-                    skPath.quadTo(pointToSkiaPoint(quadraticSegment->p[1]), pointToSkiaPoint(quadraticSegment->p[2]));
-                else if (const CubicSegment *cubicSegment = dynamic_cast<const CubicSegment *>(&**edge))
-                    skPath.cubicTo(pointToSkiaPoint(cubicSegment->p[1]), pointToSkiaPoint(cubicSegment->p[2]), pointToSkiaPoint(cubicSegment->p[3]));
+                const Point2 *p = (*edge)->controlPoints();
+                switch ((*edge)->type()) {
+                    case (int) LinearSegment::EDGE_TYPE:
+                        skPath.lineTo(pointToSkiaPoint(p[1]));
+                        break;
+                    case (int) QuadraticSegment::EDGE_TYPE:
+                        skPath.quadTo(pointToSkiaPoint(p[1]), pointToSkiaPoint(p[2]));
+                        break;
+                    case (int) CubicSegment::EDGE_TYPE:
+                        skPath.cubicTo(pointToSkiaPoint(p[1]), pointToSkiaPoint(p[2]), pointToSkiaPoint(p[3]));
+                        break;
+                }
             }
         }
     }

+ 1 - 0
main.cpp

@@ -609,6 +609,7 @@ int main(int argc, const char * const *argv) {
                     break;
                 case 'U': case 'u':
                     ++charArg;
+                    // fallthrough
                 default:
                     parseUnicode(unicode, charArg);
             }