Переглянути джерело

LibGfx: Add Path::close_all_subpaths()

Unlike Path::close() which closes only the last subpath (if possible),
this closure mechanism closes _all_ available subpaths.
AnotherTest 5 роки тому
батько
коміт
6f15f23a40
2 змінених файлів з 42 додано та 0 видалено
  1. 41 0
      Libraries/LibGfx/Path.cpp
  2. 1 0
      Libraries/LibGfx/Path.h

+ 41 - 0
Libraries/LibGfx/Path.cpp

@@ -55,6 +55,47 @@ void Path::close()
     }
 }
 
+void Path::close_all_subpaths()
+{
+    if (m_segments.size() <= 1)
+        return;
+
+    invalidate_split_lines();
+
+    Optional<FloatPoint> cursor, start_of_subpath;
+    bool is_first_point_in_subpath { false };
+
+    for (auto& segment : m_segments) {
+        switch (segment.type) {
+        case Segment::Type::MoveTo: {
+            if (cursor.has_value() && !is_first_point_in_subpath) {
+                // This is a move from a subpath to another
+                // connect the two ends of this subpath before
+                // moving on to the next one
+                ASSERT(start_of_subpath.has_value());
+
+                m_segments.append({ Segment::Type::MoveTo, cursor.value() });
+                m_segments.append({ Segment::Type::LineTo, start_of_subpath.value() });
+            }
+            is_first_point_in_subpath = true;
+            cursor = segment.point;
+            break;
+        }
+        case Segment::Type::LineTo:
+        case Segment::Type::QuadraticBezierCurveTo:
+            if (is_first_point_in_subpath) {
+                start_of_subpath = cursor;
+                is_first_point_in_subpath = false;
+            }
+            cursor = segment.point;
+            break;
+        case Segment::Type::Invalid:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+}
+
 String Path::to_string() const
 {
     StringBuilder builder;

+ 1 - 0
Libraries/LibGfx/Path.h

@@ -69,6 +69,7 @@ public:
     }
 
     void close();
+    void close_all_subpaths();
 
     struct LineSegment {
         FloatPoint from, to;