SkOpContour.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright 2013 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/core/SkTSort.h"
  8. #include "src/pathops/SkOpContour.h"
  9. #include "src/pathops/SkPathWriter.h"
  10. #include "src/pathops/SkReduceOrder.h"
  11. void SkOpContour::toPath(SkPathWriter* path) const {
  12. if (!this->count()) {
  13. return;
  14. }
  15. const SkOpSegment* segment = &fHead;
  16. do {
  17. SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
  18. } while ((segment = segment->next()));
  19. path->finishContour();
  20. path->assemble();
  21. }
  22. void SkOpContour::toReversePath(SkPathWriter* path) const {
  23. const SkOpSegment* segment = fTail;
  24. do {
  25. SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
  26. } while ((segment = segment->prev()));
  27. path->finishContour();
  28. path->assemble();
  29. }
  30. SkOpSpan* SkOpContour::undoneSpan() {
  31. SkOpSegment* testSegment = &fHead;
  32. do {
  33. if (testSegment->done()) {
  34. continue;
  35. }
  36. return testSegment->undoneSpan();
  37. } while ((testSegment = testSegment->next()));
  38. fDone = true;
  39. return nullptr;
  40. }
  41. void SkOpContourBuilder::addConic(SkPoint pts[3], SkScalar weight) {
  42. this->flush();
  43. fContour->addConic(pts, weight);
  44. }
  45. void SkOpContourBuilder::addCubic(SkPoint pts[4]) {
  46. this->flush();
  47. fContour->addCubic(pts);
  48. }
  49. void SkOpContourBuilder::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
  50. if (SkPath::kLine_Verb == verb) {
  51. this->addLine(pts);
  52. return;
  53. }
  54. SkArenaAlloc* allocator = fContour->globalState()->allocator();
  55. switch (verb) {
  56. case SkPath::kQuad_Verb: {
  57. SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(3);
  58. memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
  59. this->addQuad(ptStorage);
  60. } break;
  61. case SkPath::kConic_Verb: {
  62. SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(3);
  63. memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
  64. this->addConic(ptStorage, weight);
  65. } break;
  66. case SkPath::kCubic_Verb: {
  67. SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(4);
  68. memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
  69. this->addCubic(ptStorage);
  70. } break;
  71. default:
  72. SkASSERT(0);
  73. }
  74. }
  75. void SkOpContourBuilder::addLine(const SkPoint pts[2]) {
  76. // if the previous line added is the exact opposite, eliminate both
  77. if (fLastIsLine) {
  78. if (fLastLine[0] == pts[1] && fLastLine[1] == pts[0]) {
  79. fLastIsLine = false;
  80. return;
  81. } else {
  82. flush();
  83. }
  84. }
  85. memcpy(fLastLine, pts, sizeof(fLastLine));
  86. fLastIsLine = true;
  87. }
  88. void SkOpContourBuilder::addQuad(SkPoint pts[3]) {
  89. this->flush();
  90. fContour->addQuad(pts);
  91. }
  92. void SkOpContourBuilder::flush() {
  93. if (!fLastIsLine)
  94. return;
  95. SkArenaAlloc* allocator = fContour->globalState()->allocator();
  96. SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(2);
  97. memcpy(ptStorage, fLastLine, sizeof(fLastLine));
  98. (void) fContour->addLine(ptStorage);
  99. fLastIsLine = false;
  100. }