#include "Shape.h" namespace msdfgen { Shape::Shape() : inverseYAxis(false) { } void Shape::addContour(const Contour &contour) { contours.push_back(contour); } #ifdef MSDFGEN_USE_CPP11 void Shape::addContour(Contour &&contour) { contours.push_back((Contour &&) contour); } #endif Contour & Shape::addContour() { contours.resize(contours.size()+1); return contours.back(); } bool Shape::validate() const { for (std::vector::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) { if (!contour->edges.empty()) { Point2 corner = contour->edges.back()->point(1); for (std::vector::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { if (!*edge) return false; if ((*edge)->point(0) != corner) return false; corner = (*edge)->point(1); } } } return true; } void Shape::normalize() { for (std::vector::iterator contour = contours.begin(); contour != contours.end(); ++contour) if (contour->edges.size() == 1) { EdgeSegment *parts[3] = { }; contour->edges[0]->splitInThirds(parts[0], parts[1], parts[2]); contour->edges.clear(); contour->edges.push_back(EdgeHolder(parts[0])); contour->edges.push_back(EdgeHolder(parts[1])); contour->edges.push_back(EdgeHolder(parts[2])); } } void Shape::bound(double &l, double &b, double &r, double &t) const { for (std::vector::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) contour->bound(l, b, r, t); } void Shape::boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const { for (std::vector::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) contour->boundMiters(l, b, r, t, border, miterLimit, polarity); } Shape::Bounds Shape::getBounds(double border, double miterLimit, int polarity) const { static const double LARGE_VALUE = 1e240; Shape::Bounds bounds = { +LARGE_VALUE, +LARGE_VALUE, -LARGE_VALUE, -LARGE_VALUE }; bound(bounds.l, bounds.b, bounds.r, bounds.t); if (border > 0) { bounds.l -= border, bounds.b -= border; bounds.r += border, bounds.t += border; if (miterLimit > 0) boundMiters(bounds.l, bounds.b, bounds.r, bounds.t, border, miterLimit, polarity); } return bounds; } void Shape::scanline(Scanline &line, double y) const { std::vector intersections; double x[3]; int dy[3]; for (std::vector::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) { for (std::vector::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) { int n = (*edge)->scanlineIntersections(x, dy, y); for (int i = 0; i < n; ++i) { Scanline::Intersection intersection = { x[i], dy[i] }; intersections.push_back(intersection); } } } #ifdef MSDFGEN_USE_CPP11 line.setIntersections((std::vector &&) intersections); #else line.setIntersections(intersections); #endif } int Shape::edgeCount() const { int total = 0; for (std::vector::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) total += contour->edges.size(); return total; } }