From 0bf93ec2633cd2260ee4fb1289f4f62c67ee4d7c Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Tue, 3 Jun 2014 10:07:19 -0700 Subject: [PATCH] Fix a bunch of crashes in the vector clip tool --- src/spline.cpp | 30 ++++++++-------- src/spline.h | 23 +++++++------ src/visual_tool_vector_clip.cpp | 61 +++++++++++++++------------------ src/visual_tool_vector_clip.h | 10 ++---- 4 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/spline.cpp b/src/spline.cpp index d16034dfa..a44b1ce4d 100644 --- a/src/spline.cpp +++ b/src/spline.cpp @@ -185,11 +185,11 @@ void Spline::MovePoint(iterator curve,int point,Vector2D pos) { } } -void Spline::GetPointList(std::vector& points, std::vector& first, std::vector& count) { - points.clear(); +std::vector Spline::GetPointList(std::vector& first, std::vector& count) { first.clear(); count.clear(); + std::vector points; points.reserve((size() + 1) * 2); int curCount = 0; @@ -207,11 +207,12 @@ void Spline::GetPointList(std::vector& points, std::vector& first, s } count.push_back(curCount); + return points; } -void Spline::GetPointList(std::vector &points, iterator curve) { - points.clear(); - if (curve == end()) return; +std::vector Spline::GetPointList(iterator curve) { + std::vector points; + if (curve == end()) return points; switch (curve->type) { case SplineCurve::LINE: points.push_back(curve->p1.X()); @@ -226,9 +227,10 @@ void Spline::GetPointList(std::vector &points, iterator curve) { default: break; } + return points; } -void Spline::GetClosestParametricPoint(Vector2D reference,iterator &curve,float &t,Vector2D &pt) { +void Spline::GetClosestParametricPoint(Vector2D reference, iterator &curve, float &t, Vector2D &pt) { curve = end(); t = 0.f; if (empty()) return; @@ -237,24 +239,22 @@ void Spline::GetClosestParametricPoint(Vector2D reference,iterator &curve,float emplace_back(back().EndPoint(), front().p1); float closest = std::numeric_limits::infinity(); - for (auto cur = begin(); cur != end(); ++cur) { - float param = cur->GetClosestParam(reference); - Vector2D p1 = cur->GetPoint(param); + size_t idx = 0; + for (size_t i = 0; i < size(); ++i) { + auto& cur = (*this)[i]; + float param = cur.GetClosestParam(reference); + Vector2D p1 = cur.GetPoint(param); float dist = (p1-reference).SquareLen(); if (dist < closest) { closest = dist; t = param; - curve = cur; + idx = i; pt = p1; } } - if (&*curve == &back()) { - curve = end(); - } - - // Remove closing and return pop_back(); + curve = begin() + idx; } Vector2D Spline::GetClosestPoint(Vector2D reference) { diff --git a/src/spline.h b/src/spline.h index 2ed52a8de..2594837e8 100644 --- a/src/spline.h +++ b/src/spline.h @@ -71,9 +71,9 @@ public: void Smooth(float smooth=1.0f); /// Gets a list of points in the curve - void GetPointList(std::vector& points, std::vector& first, std::vector& count); + std::vector GetPointList(std::vector& first, std::vector& count); /// Gets a list of points in the curve - void GetPointList(std::vector &points, iterator curve); + std::vector GetPointList(iterator curve); /// Get t value and curve of the point closest to reference void GetClosestParametricPoint(Vector2D reference, iterator& curve, float &t, Vector2D &point); @@ -92,18 +92,19 @@ public: using std::vector::reverse_iterator; using std::vector::const_reverse_iterator; + using std::vector::back; using std::vector::begin; + using std::vector::clear; + using std::vector::emplace_back; + using std::vector::empty; using std::vector::end; + using std::vector::erase; + using std::vector::front; + using std::vector::insert; + using std::vector::operator[]; + using std::vector::pop_back; + using std::vector::push_back; using std::vector::rbegin; using std::vector::rend; using std::vector::size; - using std::vector::empty; - using std::vector::front; - using std::vector::back; - using std::vector::push_back; - using std::vector::pop_back; - using std::vector::emplace_back; - using std::vector::insert; - using std::vector::erase; - using std::vector::clear; }; diff --git a/src/visual_tool_vector_clip.cpp b/src/visual_tool_vector_clip.cpp index a9d002a61..fb4e4c8ed 100644 --- a/src/visual_tool_vector_clip.cpp +++ b/src/visual_tool_vector_clip.cpp @@ -14,10 +14,6 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file visual_tool_vector_clip.cpp -/// @brief Vector clipping visual typesetting tool -/// @ingroup visual_ts - #include "visual_tool_vector_clip.h" #include "ass_dialogue.h" @@ -90,11 +86,9 @@ void VisualToolVectorClip::Draw() { if (spline.empty()) return; // Parse vector - std::vector points; std::vector start; std::vector count; - - spline.GetPointList(points, start, count); + auto points = spline.GetPointList(start, count); assert(!start.empty()); assert(!count.empty()); @@ -121,8 +115,7 @@ void VisualToolVectorClip::Draw() { // Draw highlighted line if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) { - std::vector highlighted_points; - spline.GetPointList(highlighted_points, highlighted_curve); + auto highlighted_points = spline.GetPointList(highlighted_curve); if (!highlighted_points.empty()) { gl.SetLineColour(colour[2], 1.f, 2); gl.DrawLineStrip(2, highlighted_points); @@ -173,38 +166,39 @@ void VisualToolVectorClip::Draw() { gl.DrawCircle(pt, 4); } -void VisualToolVectorClip::MakeFeature(Spline::iterator cur) { +void VisualToolVectorClip::MakeFeature(size_t idx) { auto feat = agi::make_unique(); - feat->curve = cur; + feat->idx = idx; - if (cur->type == SplineCurve::POINT) { - feat->pos = cur->p1; + auto const& curve = spline[idx]; + if (curve.type == SplineCurve::POINT) { + feat->pos = curve.p1; feat->type = DRAG_SMALL_CIRCLE; feat->point = 0; } - else if (cur->type == SplineCurve::LINE) { - feat->pos = cur->p2; + else if (curve.type == SplineCurve::LINE) { + feat->pos = curve.p2; feat->type = DRAG_SMALL_CIRCLE; feat->point = 1; } - else if (cur->type == SplineCurve::BICUBIC) { + else if (curve.type == SplineCurve::BICUBIC) { // Control points - feat->pos = cur->p2; + feat->pos = curve.p2; feat->point = 1; feat->type = DRAG_SMALL_SQUARE; features.push_back(*feat.release()); feat = agi::make_unique(); - feat->curve = cur; - feat->pos = cur->p3; + feat->idx = idx; + feat->pos = curve.p3; feat->point = 2; feat->type = DRAG_SMALL_SQUARE; features.push_back(*feat.release()); // End point feat = agi::make_unique(); - feat->curve = cur; - feat->pos = cur->p4; + feat->idx = idx; + feat->pos = curve.p4; feat->point = 3; feat->type = DRAG_SMALL_CIRCLE; } @@ -215,8 +209,8 @@ void VisualToolVectorClip::MakeFeatures() { sel_features.clear(); features.clear(); active_feature = nullptr; - for (auto it = spline.begin(); it != spline.end(); ++it) - MakeFeature(it); + for (size_t i = 0; i < spline.size(); ++i) + MakeFeature(i); } void VisualToolVectorClip::Save() { @@ -239,30 +233,31 @@ void VisualToolVectorClip::Commit(wxString message) { } void VisualToolVectorClip::UpdateDrag(Feature *feature) { - spline.MovePoint(feature->curve, feature->point, feature->pos); + spline.MovePoint(spline.begin() + feature->idx, feature->point, feature->pos); } bool VisualToolVectorClip::InitializeDrag(Feature *feature) { if (mode != 5) return true; - if (feature->curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) { + auto curve = spline.begin() + feature->idx; + if (curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) { // Deleting bicubic curve handles, so convert to line - feature->curve->type = SplineCurve::LINE; - feature->curve->p2 = feature->curve->p4; + curve->type = SplineCurve::LINE; + curve->p2 = curve->p4; } else { - auto next = std::next(feature->curve); + auto next = std::next(curve); if (next != spline.end()) { - if (feature->curve->type == SplineCurve::POINT) { + if (curve->type == SplineCurve::POINT) { next->p1 = next->EndPoint(); next->type = SplineCurve::POINT; } else { - next->p1 = feature->curve->p1; + next->p1 = curve->p1; } } - spline.erase(feature->curve); + spline.erase(curve); } active_feature = nullptr; @@ -297,7 +292,7 @@ bool VisualToolVectorClip::InitializeHold() { spline.push_back(curve); sel_features.clear(); - MakeFeature(--spline.end()); + MakeFeature(spline.size() - 1); UpdateHold(); return true; } @@ -424,7 +419,7 @@ void VisualToolVectorClip::UpdateHold() { float len = (last - mouse_pos).SquareLen(); if ((mode == 6 && len >= 900) || (mode == 7 && len >= 3600)) { spline.emplace_back(last, mouse_pos); - MakeFeature(--spline.end()); + MakeFeature(spline.size() - 1); } } diff --git a/src/visual_tool_vector_clip.h b/src/visual_tool_vector_clip.h index b0c11191e..495b85d4b 100644 --- a/src/visual_tool_vector_clip.h +++ b/src/visual_tool_vector_clip.h @@ -14,11 +14,6 @@ // // Aegisub Project http://www.aegisub.org/ -/// @file visual_tool_vector_clip.h -/// @see visual_tool_vector_clip.cpp -/// @ingroup visual_ts -/// - #include "visual_feature.h" #include "visual_tool.h" #include "spline.h" @@ -30,7 +25,7 @@ class wxToolBar; /// in the spline struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeature { /// Which curve in the spline this feature is a point on - Spline::iterator curve; + size_t idx = 0; /// 0-3; indicates which part of the curve this point is int point = 0; }; @@ -51,7 +46,7 @@ class VisualToolVectorClip final : public VisualTool