Path: blob/master/thirdparty/msdfgen/core/contour-combiners.cpp
9902 views
1#include "contour-combiners.h"23#include <cfloat>4#include "arithmetics.hpp"56namespace msdfgen {78static void initDistance(double &distance) {9distance = -DBL_MAX;10}1112static void initDistance(MultiDistance &distance) {13distance.r = -DBL_MAX;14distance.g = -DBL_MAX;15distance.b = -DBL_MAX;16}1718static void initDistance(MultiAndTrueDistance &distance) {19distance.r = -DBL_MAX;20distance.g = -DBL_MAX;21distance.b = -DBL_MAX;22distance.a = -DBL_MAX;23}2425static double resolveDistance(double distance) {26return distance;27}2829static double resolveDistance(const MultiDistance &distance) {30return median(distance.r, distance.g, distance.b);31}3233template <class EdgeSelector>34SimpleContourCombiner<EdgeSelector>::SimpleContourCombiner(const Shape &shape) { }3536template <class EdgeSelector>37void SimpleContourCombiner<EdgeSelector>::reset(const Point2 &p) {38shapeEdgeSelector.reset(p);39}4041template <class EdgeSelector>42EdgeSelector &SimpleContourCombiner<EdgeSelector>::edgeSelector(int) {43return shapeEdgeSelector;44}4546template <class EdgeSelector>47typename SimpleContourCombiner<EdgeSelector>::DistanceType SimpleContourCombiner<EdgeSelector>::distance() const {48return shapeEdgeSelector.distance();49}5051template class SimpleContourCombiner<TrueDistanceSelector>;52template class SimpleContourCombiner<PerpendicularDistanceSelector>;53template class SimpleContourCombiner<MultiDistanceSelector>;54template class SimpleContourCombiner<MultiAndTrueDistanceSelector>;5556template <class EdgeSelector>57OverlappingContourCombiner<EdgeSelector>::OverlappingContourCombiner(const Shape &shape) {58windings.reserve(shape.contours.size());59for (std::vector<Contour>::const_iterator contour = shape.contours.begin(); contour != shape.contours.end(); ++contour)60windings.push_back(contour->winding());61edgeSelectors.resize(shape.contours.size());62}6364template <class EdgeSelector>65void OverlappingContourCombiner<EdgeSelector>::reset(const Point2 &p) {66this->p = p;67for (typename std::vector<EdgeSelector>::iterator contourEdgeSelector = edgeSelectors.begin(); contourEdgeSelector != edgeSelectors.end(); ++contourEdgeSelector)68contourEdgeSelector->reset(p);69}7071template <class EdgeSelector>72EdgeSelector &OverlappingContourCombiner<EdgeSelector>::edgeSelector(int i) {73return edgeSelectors[i];74}7576template <class EdgeSelector>77typename OverlappingContourCombiner<EdgeSelector>::DistanceType OverlappingContourCombiner<EdgeSelector>::distance() const {78int contourCount = (int) edgeSelectors.size();79EdgeSelector shapeEdgeSelector;80EdgeSelector innerEdgeSelector;81EdgeSelector outerEdgeSelector;82shapeEdgeSelector.reset(p);83innerEdgeSelector.reset(p);84outerEdgeSelector.reset(p);85for (int i = 0; i < contourCount; ++i) {86DistanceType edgeDistance = edgeSelectors[i].distance();87shapeEdgeSelector.merge(edgeSelectors[i]);88if (windings[i] > 0 && resolveDistance(edgeDistance) >= 0)89innerEdgeSelector.merge(edgeSelectors[i]);90if (windings[i] < 0 && resolveDistance(edgeDistance) <= 0)91outerEdgeSelector.merge(edgeSelectors[i]);92}9394DistanceType shapeDistance = shapeEdgeSelector.distance();95DistanceType innerDistance = innerEdgeSelector.distance();96DistanceType outerDistance = outerEdgeSelector.distance();97double innerScalarDistance = resolveDistance(innerDistance);98double outerScalarDistance = resolveDistance(outerDistance);99DistanceType distance;100initDistance(distance);101102int winding = 0;103if (innerScalarDistance >= 0 && fabs(innerScalarDistance) <= fabs(outerScalarDistance)) {104distance = innerDistance;105winding = 1;106for (int i = 0; i < contourCount; ++i)107if (windings[i] > 0) {108DistanceType contourDistance = edgeSelectors[i].distance();109if (fabs(resolveDistance(contourDistance)) < fabs(outerScalarDistance) && resolveDistance(contourDistance) > resolveDistance(distance))110distance = contourDistance;111}112} else if (outerScalarDistance <= 0 && fabs(outerScalarDistance) < fabs(innerScalarDistance)) {113distance = outerDistance;114winding = -1;115for (int i = 0; i < contourCount; ++i)116if (windings[i] < 0) {117DistanceType contourDistance = edgeSelectors[i].distance();118if (fabs(resolveDistance(contourDistance)) < fabs(innerScalarDistance) && resolveDistance(contourDistance) < resolveDistance(distance))119distance = contourDistance;120}121} else122return shapeDistance;123124for (int i = 0; i < contourCount; ++i)125if (windings[i] != winding) {126DistanceType contourDistance = edgeSelectors[i].distance();127if (resolveDistance(contourDistance)*resolveDistance(distance) >= 0 && fabs(resolveDistance(contourDistance)) < fabs(resolveDistance(distance)))128distance = contourDistance;129}130if (resolveDistance(distance) == resolveDistance(shapeDistance))131distance = shapeDistance;132return distance;133}134135template class OverlappingContourCombiner<TrueDistanceSelector>;136template class OverlappingContourCombiner<PerpendicularDistanceSelector>;137template class OverlappingContourCombiner<MultiDistanceSelector>;138template class OverlappingContourCombiner<MultiAndTrueDistanceSelector>;139140}141142143