libs/flake

KoSnapStrategy.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE project
00002  * Copyright (C) 2008 Jan Hambrecht <jaham@gmx.net>
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this library; see the file COPYING.LIB.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "KoSnapStrategy.h"
00021 #include "KoSnapGuide.h"
00022 #include <KoPathShape.h>
00023 #include <KoPathPoint.h>
00024 #include <KoCanvasBase.h>
00025 #include <KoViewConverter.h>
00026 #include <KoGuidesData.h>
00027 
00028 #include <QtGui/QPainter>
00029 
00030 //#include <kdebug.h>
00031 #include <math.h>
00032 
00033 
00034 KoSnapStrategy::KoSnapStrategy(KoSnapStrategy::SnapType type)
00035         : m_snapType(type)
00036 {
00037 }
00038 
00039 QPointF KoSnapStrategy::snappedPosition() const
00040 {
00041     return m_snappedPosition;
00042 }
00043 
00044 void KoSnapStrategy::setSnappedPosition(const QPointF &position)
00045 {
00046     m_snappedPosition = position;
00047 }
00048 
00049 KoSnapStrategy::SnapType KoSnapStrategy::type() const
00050 {
00051     return m_snapType;
00052 }
00053 
00054 qreal KoSnapStrategy::squareDistance(const QPointF &p1, const QPointF &p2)
00055 {
00056     qreal dx = p1.x() - p2.x();
00057     qreal dy = p1.y() - p2.y();
00058     return dx*dx + dy*dy;
00059 }
00060 
00061 qreal KoSnapStrategy::scalarProduct(const QPointF &p1, const QPointF &p2)
00062 {
00063     return p1.x() * p2.x() + p1.y() * p2.y();
00064 }
00065 
00066 OrthogonalSnapStrategy::OrthogonalSnapStrategy()
00067         : KoSnapStrategy(KoSnapStrategy::Orthogonal)
00068 {
00069 }
00070 
00071 bool OrthogonalSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00072 {
00073     QPointF horzSnap, vertSnap;
00074     qreal minVertDist = HUGE_VAL;
00075     qreal minHorzDist = HUGE_VAL;
00076 
00077     QList<KoShape*> shapes = proxy->shapes();
00078     foreach(KoShape * shape, shapes) {
00079         QList<QPointF> points = proxy->pointsFromShape(shape);
00080         foreach(const QPointF & point, points) {
00081             qreal dx = fabs(point.x() - mousePosition.x());
00082             if (dx < minHorzDist && dx < maxSnapDistance) {
00083                 minHorzDist = dx;
00084                 horzSnap = point;
00085             }
00086             qreal dy = fabs(point.y() - mousePosition.y());
00087             if (dy < minVertDist && dy < maxSnapDistance) {
00088                 minVertDist = dy;
00089                 vertSnap = point;
00090             }
00091         }
00092     }
00093 
00094     QPointF snappedPoint = mousePosition;
00095 
00096     if (minHorzDist < HUGE_VAL)
00097         snappedPoint.setX(horzSnap.x());
00098     if (minVertDist < HUGE_VAL)
00099         snappedPoint.setY(vertSnap.y());
00100 
00101     if (minHorzDist < HUGE_VAL)
00102         m_hLine = QLineF(horzSnap, snappedPoint);
00103     else
00104         m_hLine = QLineF();
00105 
00106     if (minVertDist < HUGE_VAL)
00107         m_vLine = QLineF(vertSnap, snappedPoint);
00108     else
00109         m_vLine = QLineF();
00110 
00111     setSnappedPosition(snappedPoint);
00112 
00113     return (minHorzDist < HUGE_VAL || minVertDist < HUGE_VAL);
00114 }
00115 
00116 QPainterPath OrthogonalSnapStrategy::decoration(const KoViewConverter &converter) const
00117 {
00118     Q_UNUSED(converter);
00119 
00120     QPainterPath decoration;
00121     if (! m_hLine.isNull()) {
00122         decoration.moveTo(m_hLine.p1());
00123         decoration.lineTo(m_hLine.p2());
00124     }
00125     if (! m_vLine.isNull()) {
00126         decoration.moveTo(m_vLine.p1());
00127         decoration.lineTo(m_vLine.p2());
00128     }
00129     return decoration;
00130 }
00131 
00132 NodeSnapStrategy::NodeSnapStrategy()
00133         : KoSnapStrategy(KoSnapStrategy::Node)
00134 {
00135 }
00136 
00137 bool NodeSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00138 {
00139     qreal maxDistance = maxSnapDistance * maxSnapDistance;
00140     qreal minDistance = HUGE_VAL;
00141 
00142     QRectF rect(-maxSnapDistance, -maxSnapDistance, maxSnapDistance, maxSnapDistance);
00143     rect.moveCenter(mousePosition);
00144     QList<QPointF> points = proxy->pointsInRect(rect);
00145 
00146     QPointF snappedPoint = mousePosition;
00147 
00148     foreach(const QPointF & point, points) {
00149         qreal distance = squareDistance(mousePosition, point);
00150         if (distance < maxDistance && distance < minDistance) {
00151             snappedPoint = point;
00152             minDistance = distance;
00153         }
00154     }
00155 
00156     setSnappedPosition(snappedPoint);
00157 
00158     return (minDistance < HUGE_VAL);
00159 }
00160 
00161 QPainterPath NodeSnapStrategy::decoration(const KoViewConverter &converter) const
00162 {
00163     QRectF unzoomedRect = converter.viewToDocument(QRectF(0, 0, 11, 11));
00164     unzoomedRect.moveCenter(snappedPosition());
00165     QPainterPath decoration;
00166     decoration.addEllipse(unzoomedRect);
00167     return decoration;
00168 }
00169 
00170 ExtensionSnapStrategy::ExtensionSnapStrategy()
00171         : KoSnapStrategy(KoSnapStrategy::Extension)
00172 {
00173 }
00174 
00175 bool ExtensionSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00176 {
00177     qreal maxDistance = maxSnapDistance * maxSnapDistance;
00178     qreal minDistances[2] = { HUGE_VAL, HUGE_VAL };
00179 
00180     QPointF snappedPoints[2] = { mousePosition, mousePosition };
00181     QPointF startPoints[2];
00182 
00183     QList<KoShape*> shapes = proxy->shapes(true);
00184     foreach(KoShape * shape, shapes) {
00185         KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
00186         if (! path)
00187             continue;
00188 
00189         QMatrix matrix = path->absoluteTransformation(0);
00190 
00191         int subpathCount = path->subpathCount();
00192         for (int subpathIndex = 0; subpathIndex < subpathCount; ++subpathIndex) {
00193             if (path->isClosedSubpath(subpathIndex))
00194                 continue;
00195 
00196             int pointCount = path->pointCountSubpath(subpathIndex);
00197 
00198             // check the extension from the start point
00199             KoPathPoint * first = path->pointByIndex(KoPathPointIndex(subpathIndex, 0));
00200             QPointF firstSnapPosition = mousePosition;
00201             if (snapToExtension(firstSnapPosition, first, matrix)) {
00202                 qreal distance = squareDistance(firstSnapPosition, mousePosition);
00203                 if (distance < maxDistance) {
00204                     if (distance < minDistances[0]) {
00205                         minDistances[1] = minDistances[0];
00206                         snappedPoints[1] = snappedPoints[0];
00207                         startPoints[1] = startPoints[0];
00208 
00209                         minDistances[0] = distance;
00210                         snappedPoints[0] = firstSnapPosition;
00211                         startPoints[0] = matrix.map(first->point());
00212                     }
00213                     else if (distance < minDistances[1]) {
00214                         minDistances[1] = distance;
00215                         snappedPoints[1] = firstSnapPosition;
00216                         startPoints[1] = matrix.map(first->point());
00217                     }
00218                 }
00219             }
00220 
00221             // now check the extension from the last point
00222             KoPathPoint * last = path->pointByIndex(KoPathPointIndex(subpathIndex, pointCount - 1));
00223             QPointF lastSnapPosition = mousePosition;
00224             if (snapToExtension(lastSnapPosition, last, matrix)) {
00225                 qreal distance = squareDistance(lastSnapPosition, mousePosition);
00226                 if (distance < maxDistance) {
00227                     if (distance < minDistances[0]) {
00228                         minDistances[1] = minDistances[0];
00229                         snappedPoints[1] = snappedPoints[0];
00230                         startPoints[1] = startPoints[0];
00231 
00232                         minDistances[0] = distance;
00233                         snappedPoints[0] = lastSnapPosition;
00234                         startPoints[0] = matrix.map(last->point());
00235                     }
00236                     else if (distance < minDistances[1]) {
00237                         minDistances[1] = distance;
00238                         snappedPoints[1] = lastSnapPosition;
00239                         startPoints[1] = matrix.map(last->point());
00240                     }
00241                 }
00242             }
00243         }
00244     }
00245 
00246     m_lines.clear();
00247     // if we have to extension near our mouse position, they might have an intersection
00248     // near our mouse position which we want to use as the snapped position
00249     if (minDistances[0] < HUGE_VAL && minDistances[1] < HUGE_VAL ) {
00250         // check if intersection of extension lines is near mouse position
00251         KoPathSegment s1( startPoints[0], snappedPoints[0] + snappedPoints[0]-startPoints[0] );
00252         KoPathSegment s2( startPoints[1], snappedPoints[1] + snappedPoints[1]-startPoints[1] );
00253         QList<QPointF> isects = s1.intersections( s2 );
00254         if (isects.count() == 1 && squareDistance(isects[0], mousePosition) < maxDistance) {
00255             // add both extension lines
00256             m_lines.append( QLineF(startPoints[0], isects[0]) );
00257             m_lines.append( QLineF(startPoints[1], isects[0]) );
00258             setSnappedPosition(isects[0]);
00259         }
00260         else {
00261             // only add nearest extension line of both
00262             uint index = minDistances[0] < minDistances[1] ? 0 : 1;
00263             m_lines.append( QLineF(startPoints[index], snappedPoints[index]) );
00264             setSnappedPosition(snappedPoints[index]);
00265         }
00266     }
00267     else  if (minDistances[0] < HUGE_VAL) {
00268         m_lines.append( QLineF(startPoints[0], snappedPoints[0]) );
00269         setSnappedPosition(snappedPoints[0]);
00270     }
00271     else if (minDistances[1] < HUGE_VAL) {
00272         m_lines.append( QLineF(startPoints[1], snappedPoints[1]) );
00273         setSnappedPosition(snappedPoints[1]);
00274     }
00275     else {
00276         // none of the extension lines is near our mouse position
00277         return false;
00278     }
00279 
00280     return true;
00281 }
00282 
00283 QPainterPath ExtensionSnapStrategy::decoration(const KoViewConverter &converter) const
00284 {
00285     Q_UNUSED(converter);
00286 
00287     QPainterPath decoration;
00288     foreach( const QLineF & line, m_lines ) {
00289         decoration.moveTo(line.p1());
00290         decoration.lineTo(line.p2());
00291     }
00292     return decoration;
00293 }
00294 
00295 bool ExtensionSnapStrategy::snapToExtension(QPointF &position, KoPathPoint * point, const QMatrix &matrix)
00296 {
00297     QPointF direction = extensionDirection(point, matrix);
00298     if (direction.isNull())
00299         return false;
00300 
00301     QPointF extensionStart = matrix.map(point->point());
00302     QPointF extensionStop = matrix.map(point->point()) + direction;
00303     float posOnExtension = project(extensionStart, extensionStop, position);
00304     if (posOnExtension < 0.0)
00305         return false;
00306 
00307     position = extensionStart + posOnExtension * direction;
00308     return true;
00309 }
00310 
00311 qreal ExtensionSnapStrategy::project(const QPointF &lineStart, const QPointF &lineEnd, const QPointF &point)
00312 {
00313     QPointF diff = lineEnd - lineStart;
00314     QPointF relPoint = point - lineStart;
00315     qreal diffLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
00316     if (diffLength == 0.0)
00317         return 0.0;
00318 
00319     diff /= diffLength;
00320     // project mouse position relative to stop position on extension line
00321     qreal scalar = relPoint.x() * diff.x() + relPoint.y() * diff.y();
00322     return scalar /= diffLength;
00323 }
00324 
00325 QPointF ExtensionSnapStrategy::extensionDirection(KoPathPoint * point, const QMatrix &matrix)
00326 {
00327     KoPathShape * path = point->parent();
00328     KoPathPointIndex index = path->pathPointIndex(point);
00329 
00331     if (point->properties() & KoPathPoint::StartSubpath) {
00332         if (point->activeControlPoint2()) {
00333             return matrix.map(point->point()) - matrix.map(point->controlPoint2());
00334         } else {
00335             KoPathPoint * next = path->pointByIndex(KoPathPointIndex(index.first, index.second + 1));
00336             if (! next)
00337                 return QPointF();
00338             else if (next->activeControlPoint1())
00339                 return matrix.map(point->point()) - matrix.map(next->controlPoint1());
00340             else
00341                 return matrix.map(point->point()) - matrix.map(next->point());
00342         }
00343     } else {
00344         if (point->activeControlPoint1()) {
00345             return matrix.map(point->point()) - matrix.map(point->controlPoint1());
00346         } else {
00347             KoPathPoint * prev = path->pointByIndex(KoPathPointIndex(index.first, index.second - 1));
00348             if (! prev)
00349                 return QPointF();
00350             else if (prev->activeControlPoint2())
00351                 return matrix.map(point->point()) - matrix.map(prev->controlPoint2());
00352             else
00353                 return matrix.map(point->point()) - matrix.map(prev->point());
00354         }
00355     }
00356 }
00357 
00358 IntersectionSnapStrategy::IntersectionSnapStrategy()
00359         : KoSnapStrategy(KoSnapStrategy::Intersection)
00360 {
00361 }
00362 
00363 bool IntersectionSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00364 {
00365     qreal maxDistance = maxSnapDistance * maxSnapDistance;
00366     qreal minDistance = HUGE_VAL;
00367 
00368     QRectF rect(-maxSnapDistance, -maxSnapDistance, maxSnapDistance, maxSnapDistance);
00369     rect.moveCenter(mousePosition);
00370     QPointF snappedPoint = mousePosition;
00371 
00372     QList<KoPathSegment> segments = proxy->segmentsInRect(rect);
00373     //kDebug() << "found" << segments.count() << "segments in roi";
00374 
00375     int segmentCount = segments.count();
00376     for (int i = 0; i < segmentCount; ++i) {
00377         const KoPathSegment& s1 = segments[i];
00378         for (int j = i + 1; j < segmentCount; ++j) {
00379             QList<QPointF> isects = s1.intersections(segments[j]);
00380             //kDebug() << isects.count() << "intersections found";
00381             foreach(const QPointF &point, isects) {
00382                 if (! rect.contains(point))
00383                     continue;
00384                 qreal distance = squareDistance(mousePosition, point);
00385                 if (distance < maxDistance && distance < minDistance) {
00386                     snappedPoint = point;
00387                     minDistance = distance;
00388                 }
00389             }
00390         }
00391     }
00392 
00393     setSnappedPosition(snappedPoint);
00394 
00395     return (minDistance < HUGE_VAL);
00396 }
00397 
00398 QPainterPath IntersectionSnapStrategy::decoration(const KoViewConverter &converter) const
00399 {
00400     QRectF unzoomedRect = converter.viewToDocument(QRectF(0, 0, 11, 11));
00401     unzoomedRect.moveCenter(snappedPosition());
00402     QPainterPath decoration;
00403     decoration.addRect(unzoomedRect);
00404     return decoration;
00405 }
00406 
00407 GridSnapStrategy::GridSnapStrategy()
00408         : KoSnapStrategy(KoSnapStrategy::Grid)
00409 {
00410 }
00411 
00412 bool GridSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00413 {
00414     if (! proxy->canvas()->snapToGrid())
00415         return false;
00416 
00417     // The 1e-10 here is a workaround for some weird division problem.
00418     // 360.00062366 / 2.83465058 gives 127 'exactly' when shown as a qreal,
00419     // but when casting into an int, we get 126. In fact it's 127 - 5.64e-15 !
00420     qreal gridX, gridY;
00421     proxy->canvas()->gridSize(&gridX, &gridY);
00422 
00423     // we want to snap to the nearest grid point, so calculate
00424     // the grid rows/columns before and after the points position
00425     int col = static_cast<int>(mousePosition.x() / gridX + 1e-10);
00426     int nextCol = col + 1;
00427     int row = static_cast<int>(mousePosition.y() / gridY + 1e-10);
00428     int nextRow = row + 1;
00429 
00430     // now check which grid line has less distance to the point
00431     qreal distToCol = qAbs(col * gridX - mousePosition.x());
00432     qreal distToNextCol = qAbs(nextCol * gridX - mousePosition.x());
00433     if (distToCol > distToNextCol) {
00434         col = nextCol;
00435         distToCol = distToNextCol;
00436     }
00437 
00438     qreal distToRow = qAbs(row * gridY - mousePosition.y());
00439     qreal distToNextRow = qAbs(nextRow * gridY - mousePosition.y());
00440     if (distToRow > distToNextRow) {
00441         row = nextRow;
00442         distToRow = distToNextRow;
00443     }
00444 
00445     QPointF snappedPoint = mousePosition;
00446 
00447     qreal distance = distToCol * distToCol + distToRow * distToRow;
00448     qreal maxDistance = maxSnapDistance * maxSnapDistance;
00449     // now check if we are inside the snap distance
00450     if (distance < maxDistance) {
00451         snappedPoint = QPointF(col * gridX, row * gridY);
00452     }
00453 
00454     setSnappedPosition(snappedPoint);
00455 
00456     return (distance < maxDistance);
00457 }
00458 
00459 QPainterPath GridSnapStrategy::decoration(const KoViewConverter &converter) const
00460 {
00461     QSizeF unzoomedSize = converter.viewToDocument(QSizeF(5, 5));
00462     QPainterPath decoration;
00463     decoration.moveTo(snappedPosition() - QPointF(unzoomedSize.width(), 0));
00464     decoration.lineTo(snappedPosition() + QPointF(unzoomedSize.width(), 0));
00465     decoration.moveTo(snappedPosition() - QPointF(0, unzoomedSize.height()));
00466     decoration.lineTo(snappedPosition() + QPointF(0, unzoomedSize.height()));
00467     return decoration;
00468 }
00469 
00470 BoundingBoxSnapStrategy::BoundingBoxSnapStrategy()
00471         : KoSnapStrategy(KoSnapStrategy::BoundingBox)
00472 {
00473 }
00474 
00475 bool BoundingBoxSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00476 {
00477     qreal maxDistance = maxSnapDistance * maxSnapDistance;
00478     qreal minDistance = HUGE_VAL;
00479 
00480     QRectF rect(-maxSnapDistance, -maxSnapDistance, maxSnapDistance, maxSnapDistance);
00481     rect.moveCenter(mousePosition);
00482     QPointF snappedPoint = mousePosition;
00483 
00484     KoFlake::Position pointId[5] = {
00485         KoFlake::TopLeftCorner,
00486         KoFlake::TopRightCorner,
00487         KoFlake::BottomRightCorner,
00488         KoFlake::BottomLeftCorner,
00489         KoFlake::CenteredPosition
00490     };
00491 
00492     QList<KoShape*> shapes = proxy->shapesInRect(rect, true);
00493     foreach(KoShape * shape, shapes) {
00494         qreal shapeMinDistance = HUGE_VAL;
00495         // first check the corner and center points
00496         for (int i = 0; i < 5; ++i) {
00497             m_boxPoints[i] = shape->absolutePosition(pointId[i]);
00498             qreal d = squareDistance(mousePosition, m_boxPoints[i]);
00499             if (d < minDistance && d < maxDistance) {
00500                 shapeMinDistance = d;
00501                 minDistance = d;
00502                 snappedPoint = m_boxPoints[i];
00503             }
00504         }
00505         // prioritize points over edges
00506         if (shapeMinDistance < maxDistance)
00507             continue;
00508 
00509         // now check distances to edges of bounding box
00510         for (int i = 0; i < 4; ++i) {
00511             QPointF pointOnLine;
00512             qreal d = squareDistanceToLine(m_boxPoints[i], m_boxPoints[(i+1)%4], mousePosition, pointOnLine);
00513             if (d < minDistance && d < maxDistance) {
00514                 minDistance = d;
00515                 snappedPoint = pointOnLine;
00516             }
00517         }
00518     }
00519 
00520     setSnappedPosition(snappedPoint);
00521 
00522     return (minDistance < maxDistance);
00523 
00524 }
00525 
00526 qreal BoundingBoxSnapStrategy::squareDistanceToLine(const QPointF &lineA, const QPointF &lineB, const QPointF &point, QPointF &pointOnLine)
00527 {
00528     QPointF diff = lineB - lineA;
00529     qreal diffLength = sqrt(diff.x() * diff.x() + diff.y() * diff.y());
00530     if (diffLength == 0.0f)
00531         return HUGE_VAL;
00532     // project mouse position relative to start position on line
00533     qreal scalar = KoSnapStrategy::scalarProduct(point - lineA, diff / diffLength);
00534     if (scalar < 0.0 || scalar > diffLength)
00535         return HUGE_VAL;
00536     // calculate vector between relative mouse position and projected mouse position
00537     pointOnLine = lineA + scalar / diffLength * diff;
00538     QPointF distVec = pointOnLine - point;
00539     return distVec.x()*distVec.x() + distVec.y()*distVec.y();
00540 }
00541 
00542 QPainterPath BoundingBoxSnapStrategy::decoration(const KoViewConverter &converter) const
00543 {
00544     QSizeF unzoomedSize = converter.viewToDocument(QSizeF(5, 5));
00545 
00546     QPainterPath decoration;
00547     decoration.moveTo(snappedPosition() - QPointF(unzoomedSize.width(), unzoomedSize.height()));
00548     decoration.lineTo(snappedPosition() + QPointF(unzoomedSize.width(), unzoomedSize.height()));
00549     decoration.moveTo(snappedPosition() - QPointF(unzoomedSize.width(), -unzoomedSize.height()));
00550     decoration.lineTo(snappedPosition() + QPointF(unzoomedSize.width(), -unzoomedSize.height()));
00551 
00552     return decoration;
00553 }
00554 
00555 LineGuideSnapStrategy::LineGuideSnapStrategy()
00556         : KoSnapStrategy(KoSnapStrategy::GuideLine)
00557 {
00558 }
00559 
00560 bool LineGuideSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
00561 {
00562     KoGuidesData * guidesData = proxy->canvas()->guidesData();
00563     if (! guidesData || ! guidesData->showGuideLines())
00564         return false;
00565 
00566     QPointF snappedPoint = mousePosition;
00567     m_orientation = 0;
00568 
00569     qreal minHorzDistance = maxSnapDistance;
00570     foreach(qreal guidePos, guidesData->horizontalGuideLines()) {
00571         qreal distance = qAbs(guidePos - mousePosition.y());
00572         if (distance < minHorzDistance) {
00573             snappedPoint.setY(guidePos);
00574             minHorzDistance = distance;
00575             m_orientation |= Qt::Horizontal;
00576         }
00577     }
00578     qreal minVertSnapDistance = maxSnapDistance;
00579     foreach(qreal guidePos, guidesData->verticalGuideLines()) {
00580         qreal distance = qAbs(guidePos - mousePosition.x());
00581         if (distance < minVertSnapDistance) {
00582             snappedPoint.setX(guidePos);
00583             minVertSnapDistance = distance;
00584             m_orientation |= Qt::Vertical;
00585         }
00586     }
00587 
00588     setSnappedPosition(snappedPoint);
00589 
00590     return (minHorzDistance < maxSnapDistance || minVertSnapDistance < maxSnapDistance);
00591 }
00592 
00593 QPainterPath LineGuideSnapStrategy::decoration(const KoViewConverter &converter) const
00594 {
00595     QSizeF unzoomedSize = converter.viewToDocument(QSizeF(5, 5));
00596     QPainterPath decoration;
00597     if (m_orientation & Qt::Horizontal) {
00598         decoration.moveTo(snappedPosition() - QPointF(unzoomedSize.width(), 0));
00599         decoration.lineTo(snappedPosition() + QPointF(unzoomedSize.width(), 0));
00600     }
00601     if (m_orientation & Qt::Vertical) {
00602         decoration.moveTo(snappedPosition() - QPointF(0, unzoomedSize.height()));
00603         decoration.lineTo(snappedPosition() + QPointF(0, unzoomedSize.height()));
00604     }
00605     return decoration;
00606 }