diff options
author | K. S. Ernest (iFire) Lee <fire@users.noreply.github.com> | 2021-08-27 08:51:37 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-27 08:51:37 -0700 |
commit | 90a35dac489bcbe39de35af661367519b411cb98 (patch) | |
tree | 8b6b4535556be521f9fbbadaebdea04e5316582c /thirdparty/msdfgen/core/contour-combiners.cpp | |
parent | ca4f20529c0b6588464f88fc0b0680a8df0fc77f (diff) | |
parent | 4c3f7d1290311456519ca2416590c7e62465b7f2 (diff) |
Merge pull request #51908 from bruvzg/msdf_fonts2
Make FontData importable resource. Add multi-channel SDF font rendering.
Diffstat (limited to 'thirdparty/msdfgen/core/contour-combiners.cpp')
-rw-r--r-- | thirdparty/msdfgen/core/contour-combiners.cpp | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/thirdparty/msdfgen/core/contour-combiners.cpp b/thirdparty/msdfgen/core/contour-combiners.cpp new file mode 100644 index 0000000000..d0c5b46d74 --- /dev/null +++ b/thirdparty/msdfgen/core/contour-combiners.cpp @@ -0,0 +1,133 @@ + +#include "contour-combiners.h" + +#include "arithmetics.hpp" + +namespace msdfgen { + +static void initDistance(double &distance) { + distance = SignedDistance::INFINITE.distance; +} + +static void initDistance(MultiDistance &distance) { + distance.r = SignedDistance::INFINITE.distance; + distance.g = SignedDistance::INFINITE.distance; + distance.b = SignedDistance::INFINITE.distance; +} + +static double resolveDistance(double distance) { + return distance; +} + +static double resolveDistance(const MultiDistance &distance) { + return median(distance.r, distance.g, distance.b); +} + +template <class EdgeSelector> +SimpleContourCombiner<EdgeSelector>::SimpleContourCombiner(const Shape &shape) { } + +template <class EdgeSelector> +void SimpleContourCombiner<EdgeSelector>::reset(const Point2 &p) { + shapeEdgeSelector.reset(p); +} + +template <class EdgeSelector> +EdgeSelector & SimpleContourCombiner<EdgeSelector>::edgeSelector(int) { + return shapeEdgeSelector; +} + +template <class EdgeSelector> +typename SimpleContourCombiner<EdgeSelector>::DistanceType SimpleContourCombiner<EdgeSelector>::distance() const { + return shapeEdgeSelector.distance(); +} + +template class SimpleContourCombiner<TrueDistanceSelector>; +template class SimpleContourCombiner<PseudoDistanceSelector>; +template class SimpleContourCombiner<MultiDistanceSelector>; +template class SimpleContourCombiner<MultiAndTrueDistanceSelector>; + +template <class EdgeSelector> +OverlappingContourCombiner<EdgeSelector>::OverlappingContourCombiner(const Shape &shape) { + windings.reserve(shape.contours.size()); + for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour) + windings.push_back(contour->winding()); + edgeSelectors.resize(shape.contours.size()); +} + +template <class EdgeSelector> +void OverlappingContourCombiner<EdgeSelector>::reset(const Point2 &p) { + this->p = p; + for (typename std::vector<EdgeSelector>::iterator contourEdgeSelector = edgeSelectors.begin(); contourEdgeSelector != edgeSelectors.end(); ++contourEdgeSelector) + contourEdgeSelector->reset(p); +} + +template <class EdgeSelector> +EdgeSelector & OverlappingContourCombiner<EdgeSelector>::edgeSelector(int i) { + return edgeSelectors[i]; +} + +template <class EdgeSelector> +typename OverlappingContourCombiner<EdgeSelector>::DistanceType OverlappingContourCombiner<EdgeSelector>::distance() const { + int contourCount = (int) edgeSelectors.size(); + EdgeSelector shapeEdgeSelector; + EdgeSelector innerEdgeSelector; + EdgeSelector outerEdgeSelector; + shapeEdgeSelector.reset(p); + innerEdgeSelector.reset(p); + outerEdgeSelector.reset(p); + for (int i = 0; i < contourCount; ++i) { + DistanceType edgeDistance = edgeSelectors[i].distance(); + shapeEdgeSelector.merge(edgeSelectors[i]); + if (windings[i] > 0 && resolveDistance(edgeDistance) >= 0) + innerEdgeSelector.merge(edgeSelectors[i]); + if (windings[i] < 0 && resolveDistance(edgeDistance) <= 0) + outerEdgeSelector.merge(edgeSelectors[i]); + } + + DistanceType shapeDistance = shapeEdgeSelector.distance(); + DistanceType innerDistance = innerEdgeSelector.distance(); + DistanceType outerDistance = outerEdgeSelector.distance(); + double innerScalarDistance = resolveDistance(innerDistance); + double outerScalarDistance = resolveDistance(outerDistance); + DistanceType distance; + initDistance(distance); + + int winding = 0; + if (innerScalarDistance >= 0 && fabs(innerScalarDistance) <= fabs(outerScalarDistance)) { + distance = innerDistance; + winding = 1; + for (int i = 0; i < contourCount; ++i) + if (windings[i] > 0) { + DistanceType contourDistance = edgeSelectors[i].distance(); + if (fabs(resolveDistance(contourDistance)) < fabs(outerScalarDistance) && resolveDistance(contourDistance) > resolveDistance(distance)) + distance = contourDistance; + } + } else if (outerScalarDistance <= 0 && fabs(outerScalarDistance) < fabs(innerScalarDistance)) { + distance = outerDistance; + winding = -1; + for (int i = 0; i < contourCount; ++i) + if (windings[i] < 0) { + DistanceType contourDistance = edgeSelectors[i].distance(); + if (fabs(resolveDistance(contourDistance)) < fabs(innerScalarDistance) && resolveDistance(contourDistance) < resolveDistance(distance)) + distance = contourDistance; + } + } else + return shapeDistance; + + for (int i = 0; i < contourCount; ++i) + if (windings[i] != winding) { + DistanceType contourDistance = edgeSelectors[i].distance(); + if (resolveDistance(contourDistance)*resolveDistance(distance) >= 0 && fabs(resolveDistance(contourDistance)) < fabs(resolveDistance(distance))) + distance = contourDistance; + } + if (resolveDistance(distance) == resolveDistance(shapeDistance)) + distance = shapeDistance; + return distance; +} + +template class OverlappingContourCombiner<TrueDistanceSelector>; +template class OverlappingContourCombiner<PseudoDistanceSelector>; +template class OverlappingContourCombiner<MultiDistanceSelector>; +template class OverlappingContourCombiner<MultiAndTrueDistanceSelector>; + +} |