2
0

Shape.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. int Shape::edgeCount() const {
  82. int total = 0;
  83. for (std::vector<Contour>::const_iterator contour = contours.begin(); contour != contours.end(); ++contour)
  84. total += contour->edges.size();
  85. return total;
  86. }
  87. }