| 100 | } |
| 101 | |
| 102 | void Spline::DecodeFromAss(std::string const& str) { |
| 103 | // Clear current |
| 104 | clear(); |
| 105 | std::vector<float> stack; |
| 106 | |
| 107 | // Prepare |
| 108 | char command = 'm'; |
| 109 | Vector2D pt{0, 0}; |
| 110 | |
| 111 | // Tokenize the string |
| 112 | for (auto token : agi::Split(str, ' ')) { |
| 113 | double n; |
| 114 | if (agi::util::try_parse(token, &n)) { |
| 115 | stack.push_back(n); |
| 116 | |
| 117 | // Move |
| 118 | if (stack.size() == 2 && command == 'm') { |
| 119 | pt = FromScript(Vector2D(stack[0], stack[1])); |
| 120 | stack.clear(); |
| 121 | |
| 122 | push_back(pt); |
| 123 | } |
| 124 | |
| 125 | // Line |
| 126 | if (stack.size() == 2 && command == 'l') { |
| 127 | if (empty()) push_back(pt); |
| 128 | |
| 129 | SplineCurve curve(pt, FromScript(Vector2D(stack[0], stack[1]))); |
| 130 | push_back(curve); |
| 131 | |
| 132 | pt = curve.p2; |
| 133 | stack.clear(); |
| 134 | } |
| 135 | |
| 136 | // Bicubic |
| 137 | else if (stack.size() == 6 && command == 'b') { |
| 138 | if (empty()) push_back(pt); |
| 139 | |
| 140 | SplineCurve curve(pt, |
| 141 | FromScript(Vector2D(stack[0], stack[1])), |
| 142 | FromScript(Vector2D(stack[2], stack[3])), |
| 143 | FromScript(Vector2D(stack[4], stack[5]))); |
| 144 | push_back(curve); |
| 145 | |
| 146 | pt = curve.p4; |
| 147 | stack.clear(); |
| 148 | } |
| 149 | } |
| 150 | // Got something else |
| 151 | else if (token.size() == 1) { |
| 152 | command = token[0]; |
| 153 | stack.clear(); |
| 154 | } |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | void Spline::MovePoint(iterator curve,int point,Vector2D pos) { |
| 159 | auto prev = std::prev(curve, curve != begin()); |