| 63 | } |
| 64 | |
| 65 | void Shape::normalize() { |
| 66 | for (std::vector<Contour>::iterator contour = contours.begin(); contour != contours.end(); ++contour) { |
| 67 | if (contour->edges.size() == 1) { |
| 68 | EdgeSegment *parts[3] = { }; |
| 69 | contour->edges[0]->splitInThirds(parts[0], parts[1], parts[2]); |
| 70 | contour->edges.clear(); |
| 71 | contour->edges.push_back(EdgeHolder(parts[0])); |
| 72 | contour->edges.push_back(EdgeHolder(parts[1])); |
| 73 | contour->edges.push_back(EdgeHolder(parts[2])); |
| 74 | } else if (!contour->edges.empty()) { |
| 75 | // Push apart convergent edge segments |
| 76 | EdgeHolder *prevEdge = &contour->edges.back(); |
| 77 | for (std::vector<EdgeHolder>::iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { |
| 78 | Vector2 prevDir = (*prevEdge)->direction(1).normalize(); |
| 79 | Vector2 curDir = (*edge)->direction(0).normalize(); |
| 80 | if (dotProduct(prevDir, curDir) < MSDFGEN_CORNER_DOT_EPSILON-1) { |
| 81 | double factor = DECONVERGE_OVERSHOOT*sqrt(1-(MSDFGEN_CORNER_DOT_EPSILON-1)*(MSDFGEN_CORNER_DOT_EPSILON-1))/(MSDFGEN_CORNER_DOT_EPSILON-1); |
| 82 | Vector2 axis = factor*(curDir-prevDir).normalize(); |
| 83 | if (convergentCurveOrdering(*prevEdge, *edge) < 0) |
| 84 | axis = -axis; |
| 85 | deconvergeEdge(*prevEdge, 1, axis.getOrthogonal(true)); |
| 86 | deconvergeEdge(*edge, 0, axis.getOrthogonal(false)); |
| 87 | } |
| 88 | prevEdge = &*edge; |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | void Shape::bound(double &xMin, double &yMin, double &xMax, double &yMax) const { |
| 95 | for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) |
no test coverage detected