178{
179 Q_ASSERT(std::isfinite(maxSnapDistance));
180
181 const qreal maxDistance = maxSnapDistance * maxSnapDistance;
182 qreal minDistances[2] = { HUGE_VAL, HUGE_VAL };
183
184 QPointF snappedPoints[2] = { mousePosition, mousePosition };
185 QPointF startPoints[2];
186
188
189 Q_FOREACH (
KoShape * shape, shapes) {
191 if (! path) {
192 continue;
193 }
195
196 const int subpathCount = path->subpathCount();
197 for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
198 if (path->isClosedSubpath(subpathIndex))
199 continue;
200
201 int pointCount = path->subpathPointCount(subpathIndex);
202
203
205 QPointF firstSnapPosition = mousePosition;
210 minDistances[1] = minDistances[0];
211 snappedPoints[1] = snappedPoints[0];
212 startPoints[1] = startPoints[0];
213
215 snappedPoints[0] = firstSnapPosition;
216 startPoints[0] = matrix.map(first->
point());
217 }
218 else if (
distance < minDistances[1]) {
220 snappedPoints[1] = firstSnapPosition;
221 startPoints[1] = matrix.map(first->
point());
222 }
223 }
224 }
225
226
228 QPointF lastSnapPosition = mousePosition;
233 minDistances[1] = minDistances[0];
234 snappedPoints[1] = snappedPoints[0];
235 startPoints[1] = startPoints[0];
236
238 snappedPoints[0] = lastSnapPosition;
239 startPoints[0] = matrix.map(last->
point());
240 }
241 else if (
distance < minDistances[1]) {
243 snappedPoints[1] = lastSnapPosition;
244 startPoints[1] = matrix.map(last->
point());
245 }
246 }
247 }
248 }
249 }
250
252
253
254 if (minDistances[0] < HUGE_VAL && minDistances[1] < HUGE_VAL) {
255
256 KoPathSegment s1(startPoints[0], snappedPoints[0] + snappedPoints[0]-startPoints[0]);
257 KoPathSegment s2(startPoints[1], snappedPoints[1] + snappedPoints[1]-startPoints[1]);
259 if (isects.count() == 1 &&
squareDistance(isects[0], mousePosition) < maxDistance) {
260
261 m_lines.append(QLineF(startPoints[0], isects[0]));
262 m_lines.append(QLineF(startPoints[1], isects[0]));
264 }
265 else {
266
267 uint index = minDistances[0] < minDistances[1] ? 0 : 1;
268 m_lines.append(QLineF(startPoints[index], snappedPoints[index]));
270 }
271 }
272 else if (minDistances[0] < HUGE_VAL) {
273 m_lines.append(QLineF(startPoints[0], snappedPoints[0]));
275 }
276 else if (minDistances[1] < HUGE_VAL) {
277 m_lines.append(QLineF(startPoints[1], snappedPoints[1]));
279 }
280 else {
281
282 return false;
283 }
284 return true;
285}
qreal distance(const QPointF &p1, const QPointF &p2)
bool snapToExtension(QPointF &position, KoPathPoint *point, const QTransform &matrix)
A KoPathSegment consist of two neighboring KoPathPoints.
QTransform absoluteTransformation() const
QList< KoShape * > shapes(bool omitEditedShape=false)
returns list of all shapes
void setSnappedPosition(const QPointF &position, SnapType snapType)
sets the current snapped position
static qreal squareDistance(const QPointF &p1, const QPointF &p2)