2
0

export-svg.cpp 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "export-svg.h"
  2. #include <cstdio>
  3. #include "edge-segments.h"
  4. namespace msdfgen {
  5. static void writeSvgCoord(FILE *f, Point2 coord) {
  6. fprintf(f, "%.17g %.17g", coord.x, coord.y);
  7. }
  8. static void writeSvgPathDef(FILE *f, const Shape &shape) {
  9. bool beginning = true;
  10. for (const Contour &c : shape.contours) {
  11. if (c.edges.empty())
  12. continue;
  13. if (beginning)
  14. beginning = false;
  15. else
  16. fputc(' ', f);
  17. fputs("M ", f);
  18. writeSvgCoord(f, c.edges[0]->controlPoints()[0]);
  19. for (const EdgeHolder &e : c.edges) {
  20. const Point2 *cp = e->controlPoints();
  21. switch (e->type()) {
  22. case (int) LinearSegment::EDGE_TYPE:
  23. fputs(" L ", f);
  24. writeSvgCoord(f, cp[1]);
  25. break;
  26. case (int) QuadraticSegment::EDGE_TYPE:
  27. fputs(" Q ", f);
  28. writeSvgCoord(f, cp[1]);
  29. fputc(' ', f);
  30. writeSvgCoord(f, cp[2]);
  31. break;
  32. case (int) CubicSegment::EDGE_TYPE:
  33. fputs(" C ", f);
  34. writeSvgCoord(f, cp[1]);
  35. fputc(' ', f);
  36. writeSvgCoord(f, cp[2]);
  37. fputc(' ', f);
  38. writeSvgCoord(f, cp[3]);
  39. break;
  40. }
  41. }
  42. fputs(" Z", f);
  43. }
  44. }
  45. bool saveSvgShape(const Shape &shape, const char *filename) {
  46. if (FILE *f = fopen(filename, "w")) {
  47. fputs("<svg xmlns=\"http://www.w3.org/2000/svg\"><path", f);
  48. if (!shape.inverseYAxis)
  49. fputs(" transform=\"scale(1 -1)\"", f);
  50. fputs(" d=\"", f);
  51. writeSvgPathDef(f, shape);
  52. fputs("\"/></svg>\n", f);
  53. fclose(f);
  54. return true;
  55. }
  56. return false;
  57. }
  58. bool saveSvgShape(const Shape &shape, const Shape::Bounds &bounds, const char *filename) {
  59. if (FILE *f = fopen(filename, "w")) {
  60. fprintf(f, "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"%.17g %.17g %.17g %.17g\"><path", bounds.l, bounds.b, bounds.r-bounds.l, bounds.t-bounds.b);
  61. if (!shape.inverseYAxis)
  62. fprintf(f, " transform=\"translate(0 %.17g) scale(1 -1)\"", bounds.b+bounds.t);
  63. fputs(" d=\"", f);
  64. writeSvgPathDef(f, shape);
  65. fputs("\"/></svg>\n", f);
  66. fclose(f);
  67. return true;
  68. }
  69. return false;
  70. }
  71. }