Shape.cpp 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #include "Shape.h"
  2. namespace msdfgen {
  3. Shape::Shape() : inverseYAxis(false) { }
  4. void Shape::addContour(const Contour &contour) {
  5. contours.push_back(contour);
  6. }
  7. #ifdef MSDFGEN_USE_CPP11
  8. void Shape::addContour(Contour &&contour) {
  9. contours.push_back((Contour &&) contour);
  10. }
  11. #endif
  12. Contour & Shape::addContour() {
  13. contours.resize(contours.size()+1);
  14. return contours.back();
  15. }
  16. bool Shape::validate() const {
  17. for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) {
  18. if (!contour->edges.empty()) {
  19. Point2 corner = contour->edges.back()->point(1);
  20. for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
  21. if (!*edge)
  22. return false;
  23. if ((*edge)->point(0) != corner)
  24. return false;
  25. corner = (*edge)->point(1);
  26. }
  27. }
  28. }
  29. return true;
  30. }
  31. void Shape::normalize() {
  32. for (std::vector<Contour>::iterator contour = contours.begin(); contour != contours.end(); ++contour)
  33. if (contour->edges.size() == 1) {
  34. EdgeSegment *parts[3] = { };
  35. contour->edges[0]->splitInThirds(parts[0], parts[1], parts[2]);
  36. contour->edges.clear();
  37. contour->edges.push_back(EdgeHolder(parts[0]));
  38. contour->edges.push_back(EdgeHolder(parts[1]));
  39. contour->edges.push_back(EdgeHolder(parts[2]));
  40. }
  41. }
  42. void Shape::bound(double &l, double &b, double &r, double &t) const {
  43. for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
  44. contour->bound(l, b, r, t);
  45. }
  46. void Shape::boundMiters(double &l, double &b, double &r, double &t, double border, double miterLimit, int polarity) const {
  47. for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
  48. contour->boundMiters(l, b, r, t, border, miterLimit, polarity);
  49. }
  50. Shape::Bounds Shape::getBounds(double border, double miterLimit, int polarity) const {
  51. static const double LARGE_VALUE = 1e240;
  52. Shape::Bounds bounds = { +LARGE_VALUE, +LARGE_VALUE, -LARGE_VALUE, -LARGE_VALUE };
  53. bound(bounds.l, bounds.b, bounds.r, bounds.t);
  54. if (border > 0) {
  55. bounds.l -= border, bounds.b -= border;
  56. bounds.r += border, bounds.t += border;
  57. if (miterLimit > 0)
  58. boundMiters(bounds.l, bounds.b, bounds.r, bounds.t, border, miterLimit, polarity);
  59. }
  60. return bounds;
  61. }
  62. void Shape::scanline(Scanline &line, double y) const {
  63. std::vector<Scanline::Intersection> intersections;
  64. double x[3];
  65. int dy[3];
  66. for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour) {
  67. for (std::vector<EdgeHolder>::const_iterator edge = contour->edges.begin(); edge != contour->edges.end(); ++edge) {
  68. int n = (*edge)->scanlineIntersections(x, dy, y);
  69. for (int i = 0; i < n; ++i) {
  70. Scanline::Intersection intersection = { x[i], dy[i] };
  71. intersections.push_back(intersection);
  72. }
  73. }
  74. }
  75. #ifdef MSDFGEN_USE_CPP11
  76. line.setIntersections((std::vector<Scanline::Intersection> &&) intersections);
  77. #else
  78. line.setIntersections(intersections);
  79. #endif
  80. }
  81. }