rasterization.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #include "rasterization.h"
  2. #include <vector>
  3. #include "arithmetics.hpp"
  4. namespace msdfgen {
  5. void rasterize(BitmapSection<float, 1> output, const Shape &shape, const Projection &projection, FillRule fillRule) {
  6. output.reorient(shape.getYAxisOrientation());
  7. Scanline scanline;
  8. for (int y = 0; y < output.height; ++y) {
  9. shape.scanline(scanline, projection.unprojectY(y+.5));
  10. for (int x = 0; x < output.width; ++x)
  11. *output(x, y) = (float) scanline.filled(projection.unprojectX(x+.5), fillRule);
  12. }
  13. }
  14. void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
  15. sdf.reorient(shape.getYAxisOrientation());
  16. float doubleSdfZeroValue = sdfZeroValue+sdfZeroValue;
  17. Scanline scanline;
  18. for (int y = 0; y < sdf.height; ++y) {
  19. shape.scanline(scanline, projection.unprojectY(y+.5));
  20. for (int x = 0; x < sdf.width; ++x) {
  21. bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
  22. float &sd = *sdf(x, y);
  23. if ((sd > sdfZeroValue) != fill)
  24. sd = doubleSdfZeroValue-sd;
  25. }
  26. }
  27. }
  28. template <int N>
  29. static void multiDistanceSignCorrection(BitmapSection<float, N> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
  30. int w = sdf.width, h = sdf.height;
  31. if (!(w && h))
  32. return;
  33. sdf.reorient(shape.getYAxisOrientation());
  34. float doubleSdfZeroValue = sdfZeroValue+sdfZeroValue;
  35. Scanline scanline;
  36. bool ambiguous = false;
  37. std::vector<char> matchMap;
  38. matchMap.resize(w*h);
  39. char *match = &matchMap[0];
  40. for (int y = 0; y < h; ++y) {
  41. shape.scanline(scanline, projection.unprojectY(y+.5));
  42. for (int x = 0; x < w; ++x) {
  43. bool fill = scanline.filled(projection.unprojectX(x+.5), fillRule);
  44. float *msd = sdf(x, y);
  45. float sd = median(msd[0], msd[1], msd[2]);
  46. if (sd == sdfZeroValue)
  47. ambiguous = true;
  48. else if ((sd > sdfZeroValue) != fill) {
  49. msd[0] = doubleSdfZeroValue-msd[0];
  50. msd[1] = doubleSdfZeroValue-msd[1];
  51. msd[2] = doubleSdfZeroValue-msd[2];
  52. *match = -1;
  53. } else
  54. *match = 1;
  55. if (N >= 4 && (msd[3] > sdfZeroValue) != fill)
  56. msd[3] = doubleSdfZeroValue-msd[3];
  57. ++match;
  58. }
  59. }
  60. // This step is necessary to avoid artifacts when whole shape is inverted
  61. if (ambiguous) {
  62. match = &matchMap[0];
  63. for (int y = 0; y < h; ++y) {
  64. for (int x = 0; x < w; ++x) {
  65. if (!*match) {
  66. int neighborMatch = 0;
  67. if (x > 0) neighborMatch += *(match-1);
  68. if (x < w-1) neighborMatch += *(match+1);
  69. if (y > 0) neighborMatch += *(match-w);
  70. if (y < h-1) neighborMatch += *(match+w);
  71. if (neighborMatch < 0) {
  72. float *msd = sdf(x, y);
  73. msd[0] = doubleSdfZeroValue-msd[0];
  74. msd[1] = doubleSdfZeroValue-msd[1];
  75. msd[2] = doubleSdfZeroValue-msd[2];
  76. }
  77. }
  78. ++match;
  79. }
  80. }
  81. }
  82. }
  83. void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
  84. multiDistanceSignCorrection(sdf, shape, projection, sdfZeroValue, fillRule);
  85. }
  86. void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, float sdfZeroValue, FillRule fillRule) {
  87. multiDistanceSignCorrection(sdf, shape, projection, sdfZeroValue, fillRule);
  88. }
  89. // Legacy API
  90. void rasterize(const BitmapSection<float, 1> &output, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
  91. rasterize(output, shape, Projection(scale, translate), fillRule);
  92. }
  93. void distanceSignCorrection(BitmapSection<float, 1> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
  94. distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
  95. }
  96. void distanceSignCorrection(BitmapSection<float, 3> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
  97. distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
  98. }
  99. void distanceSignCorrection(BitmapSection<float, 4> sdf, const Shape &shape, const Projection &projection, FillRule fillRule) {
  100. distanceSignCorrection(sdf, shape, projection, .5f, fillRule);
  101. }
  102. void distanceSignCorrection(const BitmapSection<float, 1> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
  103. distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
  104. }
  105. void distanceSignCorrection(const BitmapSection<float, 3> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
  106. distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
  107. }
  108. void distanceSignCorrection(const BitmapSection<float, 4> &sdf, const Shape &shape, const Vector2 &scale, const Vector2 &translate, FillRule fillRule) {
  109. distanceSignCorrection(sdf, shape, Projection(scale, translate), fillRule);
  110. }
  111. }