From 052f5fffd78066fbd276504cfc099cca006274b5 Mon Sep 17 00:00:00 2001 From: Chlumsky Date: Mon, 24 Jul 2023 20:53:08 +0200 Subject: [PATCH] Removed dynamic_cast --- core/Shape.cpp | 15 ++++----- core/edge-segments.cpp | 24 ++++++++++++++ core/edge-segments.h | 22 +++++++++++++ core/shape-description.cpp | 59 ++++++++++++++++++---------------- ext/resolve-shape-geometry.cpp | 18 +++++++---- main.cpp | 1 + 6 files changed, 96 insertions(+), 43 deletions(-) diff --git a/core/Shape.cpp b/core/Shape.cpp index f4449ba..5b2d0f6 100644 --- a/core/Shape.cpp +++ b/core/Shape.cpp @@ -40,15 +40,12 @@ bool Shape::validate() const { } static void deconvergeEdge(EdgeHolder &edgeHolder, int param) { - { - const QuadraticSegment *quadraticSegment = dynamic_cast(&*edgeHolder); - if (quadraticSegment) - edgeHolder = quadraticSegment->convertToCubic(); - } - { - CubicSegment *cubicSegment = dynamic_cast(&*edgeHolder); - if (cubicSegment) - cubicSegment->deconverge(param, MSDFGEN_DECONVERGENCE_FACTOR); + switch (edgeHolder->type()) { + case (int) QuadraticSegment::EDGE_TYPE: + edgeHolder = static_cast(&*edgeHolder)->convertToCubic(); + // fallthrough + case (int) CubicSegment::EDGE_TYPE: + static_cast(&*edgeHolder)->deconverge(param, MSDFGEN_DECONVERGENCE_FACTOR); } } diff --git a/core/edge-segments.cpp b/core/edge-segments.cpp index 5274a9a..d2fd1c9 100644 --- a/core/edge-segments.cpp +++ b/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); } diff --git a/core/edge-segments.h b/core/edge-segments.h index 1c8fb59..d800473 100644 --- a/core/edge-segments.h +++ b/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; diff --git a/core/shape-description.cpp b/core/shape-description.cpp index a096fa2..32c515d 100644 --- a/core/shape-description.cpp +++ b/core/shape-description.cpp @@ -244,34 +244,37 @@ bool writeShapeDescription(FILE *output, const Shape &shape) { default:; } } - if (const LinearSegment *e = dynamic_cast(&**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(&**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(&**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"); diff --git a/ext/resolve-shape-geometry.cpp b/ext/resolve-shape-geometry.cpp index cd78d48..765277a 100644 --- a/ext/resolve-shape-geometry.cpp +++ b/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::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { - if (const LinearSegment *linearSegment = dynamic_cast(&**edge)) - skPath.lineTo(pointToSkiaPoint(linearSegment->p[1])); - else if (const QuadraticSegment *quadraticSegment = dynamic_cast(&**edge)) - skPath.quadTo(pointToSkiaPoint(quadraticSegment->p[1]), pointToSkiaPoint(quadraticSegment->p[2])); - else if (const CubicSegment *cubicSegment = dynamic_cast(&**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; + } } } } diff --git a/main.cpp b/main.cpp index 05317b9..73a3478 100644 --- a/main.cpp +++ b/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); }