#include "MSDFErrorCorrection.h" #include #include "arithmetics.hpp" #include "equation-solver.h" #include "EdgeColor.h" #include "bitmap-interpolation.hpp" #include "edge-selectors.h" #include "contour-combiners.h" #include "ShapeDistanceFinder.h" #include "generator-config.h" namespace msdfgen { #define ARTIFACT_T_EPSILON .01 #define PROTECTION_RADIUS_TOLERANCE 1.001 #define CLASSIFIER_FLAG_CANDIDATE 0x01 #define CLASSIFIER_FLAG_ARTIFACT 0x02 MSDFGEN_PUBLIC const double ErrorCorrectionConfig::defaultMinDeviationRatio = 1.11111111111111111; MSDFGEN_PUBLIC const double ErrorCorrectionConfig::defaultMinImproveRatio = 1.11111111111111111; /// The base artifact classifier recognizes artifacts based on the contents of the SDF alone. class BaseArtifactClassifier { public: inline BaseArtifactClassifier(double span, bool protectedFlag) : span(span), protectedFlag(protectedFlag) { } /// Evaluates if the median value xm interpolated at xt in the range between am at at and bm at bt indicates an artifact. inline int rangeTest(double at, double bt, double xt, float am, float bm, float xm) const { // For protected texels, only consider inversion artifacts (interpolated median has different sign than boundaries). For the rest, it is sufficient that the interpolated median is outside its boundaries. if ((am > .5f && bm > .5f && xm <= .5f) || (am < .5f && bm < .5f && xm >= .5f) || (!protectedFlag && median(am, bm, xm) != xm)) { double axSpan = (xt-at)*span, bxSpan = (bt-xt)*span; // Check if the interpolated median's value is in the expected range based on its distance (span) from boundaries a, b. if (!(xm >= am-axSpan && xm <= am+axSpan && xm >= bm-bxSpan && xm <= bm+bxSpan)) return CLASSIFIER_FLAG_CANDIDATE|CLASSIFIER_FLAG_ARTIFACT; return CLASSIFIER_FLAG_CANDIDATE; } return 0; } /// Returns true if the combined results of the tests performed on the median value m interpolated at t indicate an artifact. inline bool evaluate(double t, float m, int flags) const { return (flags&2) != 0; } private: double span; bool protectedFlag; }; /// The shape distance checker evaluates the exact shape distance to find additional artifacts at a significant performance cost. template