예제 #1
0
void KoPathPointInsertCommand::undo()
{
    QUndoCommand::undo();
    for (int i = 0; i < m_pointDataList.size(); ++i) {
        const KoPathPointData &pdBefore = m_pointDataList.at(i);
        KoPathShape * pathShape = pdBefore.pathShape;
        KoPathPointIndex piAfter = pdBefore.pointIndex;
        ++piAfter.second;

        KoPathPoint * before = pathShape->pointByIndex(pdBefore.pointIndex);

        m_points[i] = pathShape->removePoint(piAfter);

        if (m_points[i]->properties() & KoPathPoint::CloseSubpath) {
            piAfter.second = 0;
        }

        KoPathPoint * after = pathShape->pointByIndex(piAfter);

        if (before->activeControlPoint2()) {
            QPointF controlPoint2 = before->controlPoint2();
            qSwap(controlPoint2, m_controlPoints[i].first);
            before->setControlPoint2(controlPoint2);
        }

        if (after->activeControlPoint1()) {
            QPointF controlPoint1 = after->controlPoint1();
            qSwap(controlPoint1, m_controlPoints[i].second);
            after->setControlPoint1(controlPoint1);
        }
        pathShape->update();
    }
    m_deletePoints = true;
}
void KoPathSegmentTypeCommand::redo()
{
    KUndo2Command::redo();
    QList<KoPathPointData>::const_iterator it(m_pointDataList.constBegin());
    for (; it != m_pointDataList.constEnd(); ++it) {
        KoPathShape * pathShape = it->pathShape;
        pathShape->update();

        KoPathSegment segment = pathShape->segmentByIndex(it->pointIndex);

        if (m_segmentType == Curve) {
            // we change type to curve -> set control point positions
            QPointF pointDiff = segment.second()->point() - segment.first()->point();
            segment.first()->setControlPoint2(segment.first()->point() + pointDiff / 3.0);
            segment.second()->setControlPoint1(segment.first()->point() + pointDiff * 2.0 / 3.0);
        } else {
            // we are changing type to line -> remove control points
            segment.first()->removeControlPoint2();
            segment.second()->removeControlPoint1();
        }

        pathShape->normalize();
        pathShape->update();
    }
}
예제 #3
0
void SvgStyleWriter::saveSvgClipping(KoShape *shape, SvgSavingContext &context)
{
    KoClipPath *clipPath = shape->clipPath();
    if (!clipPath)
        return;

    const QSizeF shapeSize = shape->outlineRect().size();
    KoPathShape *path = KoPathShape::createShapeFromPainterPath(clipPath->pathForSize(shapeSize));
    if (!path)
        return;

    path->close();

    const QString uid = context.createUID("clippath");

    context.styleWriter().startElement("clipPath");
    context.styleWriter().addAttribute("id", uid);
    context.styleWriter().addAttribute("clipPathUnits", "userSpaceOnUse");

    context.styleWriter().startElement("path");
    context.styleWriter().addAttribute("d", path->toString(path->absoluteTransformation(0)*context.userSpaceTransform()));
    context.styleWriter().endElement(); // path

    context.styleWriter().endElement(); // clipPath

    context.shapeWriter().addAttribute("clip-path", "url(#" + uid + ")");
    if (clipPath->clipRule() != Qt::WindingFill)
        context.shapeWriter().addAttribute("clip-rule", "evenodd");
}
예제 #4
0
void SvgStyleWriter::saveSvgFill(KoShape *shape, SvgSavingContext &context)
{
    if (! shape->background()) {
        context.shapeWriter().addAttribute("fill", "none");
    }

    QBrush fill(Qt::NoBrush);
    QSharedPointer<KoColorBackground>  cbg = qSharedPointerDynamicCast<KoColorBackground>(shape->background());
    if (cbg) {
        context.shapeWriter().addAttribute("fill", cbg->color().name());
        if (cbg->color().alphaF() < 1.0)
            context.shapeWriter().addAttribute("fill-opacity", cbg->color().alphaF());
    }
    QSharedPointer<KoGradientBackground>  gbg = qSharedPointerDynamicCast<KoGradientBackground>(shape->background());
    if (gbg) {
        QString gradientId = saveSvgGradient(gbg->gradient(), gbg->transform(), context);
        context.shapeWriter().addAttribute("fill", "url(#" + gradientId + ")");
    }
    QSharedPointer<KoPatternBackground>  pbg = qSharedPointerDynamicCast<KoPatternBackground>(shape->background());
    if (pbg) {
        const QString patternId = saveSvgPattern(pbg, shape, context);
        context.shapeWriter().addAttribute("fill", "url(#" + patternId + ")");
    }

    KoPathShape * path = dynamic_cast<KoPathShape*>(shape);
    if (path && shape->background()) {
        // non-zero is default, so only write fillrule if evenodd is set
        if (path->fillRule() == Qt::OddEvenFill)
            context.shapeWriter().addAttribute("fill-rule", "evenodd");
    }
}
예제 #5
0
QList<KoSubpath *> KarbonSimplifyPath::split( const KoPathShape &path )
{
    QList<KoSubpath *> res;
    KoSubpath *subpath = new KoSubpath;
    res.append( subpath );

    for ( int i = 0; i < path.pointCount(); ++i )
    {
        KoPathPoint *p = path.pointByIndex( KoPathPointIndex(0, i) );
        // if the path separates two subpaths
        // (if it isn't smooth nor the first or last point)
        if ( i != 0  &&  i != path.pointCount()-1 )
        {
            KoPathPoint *prev = path.pointByIndex( KoPathPointIndex(0, i-1) );
            KoPathPoint *next = path.pointByIndex( KoPathPointIndex(0, i+1) );
            if ( ! p->isSmooth(prev, next) )
            {
                // create a new subpath
                subpath->append( new KoPathPoint(*p) );
                subpath = new KoSubpath;
                res.append( subpath );
            }
        }
        subpath->append( new KoPathPoint(*p) );
    }

    return res;
}
예제 #6
0
void KoPathPointInsertCommand::redo()
{
    QUndoCommand::redo();
    for (int i = m_pointDataList.size() - 1; i >= 0; --i) {
        KoPathPointData pointData = m_pointDataList.at(i);
        KoPathShape * pathShape = pointData.pathShape;

        KoPathSegment segment = pathShape->segmentByIndex(pointData.pointIndex);

        ++pointData.pointIndex.second;

        if (segment.first()->activeControlPoint2()) {
            QPointF controlPoint2 = segment.first()->controlPoint2();
            qSwap(controlPoint2, m_controlPoints[i].first);
            segment.first()->setControlPoint2(controlPoint2);
        }

        if (segment.second()->activeControlPoint1()) {
            QPointF controlPoint1 = segment.second()->controlPoint1();
            qSwap(controlPoint1, m_controlPoints[i].second);
            segment.second()->setControlPoint1(controlPoint1);
        }

        pathShape->insertPoint(m_points.at(i), pointData.pointIndex);
        pathShape->update();
    }
    m_deletePoints = false;
}
void TestSegmentTypeCommand::changeToLine()
{
    KoPathShape path;
    path.moveTo( QPointF(0,0) );
    path.curveTo( QPointF(25,25), QPointF(75,25), QPointF(100,0) );

    KoPathPointData segment(&path, KoPathPointIndex(0,0));
    QList<KoPathPointData> segments;
    segments.append(segment);

    // get first segment
    KoPathSegment s = path.segmentByIndex(KoPathPointIndex(0,0));

    KoPathSegmentTypeCommand cmd(segments, KoPathSegmentTypeCommand::Line);

    QVERIFY(s.first()->activeControlPoint2());
    QVERIFY(s.second()->activeControlPoint1());

    cmd.redo();

    QVERIFY(!s.first()->activeControlPoint2());
    QVERIFY(!s.second()->activeControlPoint1());

    cmd.undo();

    QVERIFY(s.first()->activeControlPoint2());
    QVERIFY(s.second()->activeControlPoint1());
}
 PointData( KoPathPoint * p )
 {
     KoPathShape * shape = p->parent();
     // save points in document coordinates
     oldNode = shape->shapeToDocument( p->point() );
     oldControlPoint1 = shape->shapeToDocument( p->controlPoint1() );
     oldControlPoint2 = shape->shapeToDocument( p->controlPoint2() );
 }
 void restorePoint( KoPathPoint * p )
 {
     KoPathShape * shape = p->parent();
     p->setPoint( shape->documentToShape( oldNode ) );
     if( p->activeControlPoint1() )
         p->setControlPoint1( shape->documentToShape( oldControlPoint1 ) );
     if( p->activeControlPoint2() )
         p->setControlPoint2( shape->documentToShape( oldControlPoint2 ) );
 }
예제 #10
0
void KoShapeStroke::Private::paintBorder(KoShape *shape, QPainter &painter, const QPen &pen) const
{
    if (!pen.isCosmetic()) {
        KoPathShape *pathShape = dynamic_cast<KoPathShape *>(shape);
        if (pathShape) {
            QPainterPath path = pathShape->pathStroke(pen);
            painter.fillPath(path, pen.brush());
            return;
        }
        painter.strokePath(shape->outline(), pen);
    }
}
예제 #11
0
KoClipPath *PictureShape::generateClipPath()
{
    QPainterPath path = _Private::generateOutline(imageData()->image());
    path = path * QTransform().scale(size().width(), size().height());

    KoPathShape *pathShape = KoPathShape::createShapeFromPainterPath(path);

    //createShapeFromPainterPath converts the path topleft into a shape topleft
    //and the pathShape needs to be on top of us. So to preserve both we do:
    pathShape->setTransformation(pathShape->transformation() * transformation());

    return new KoClipPath(this, new KoClipData(pathShape));
}
예제 #12
0
void TestPACopyPastePage::addShape( KoPAPageBase * page )
{
    KoPathShape * path = new KoPathShape();
    path->lineTo( QPointF( 10, 0 ) );
    path->lineTo( QPointF( 10, 10 ) );
    path->setPosition( m_pos );
    m_pos += QPointF( 1.0, 1.0 );

    QList<KoShape*> shapes = page->shapes();
    if ( !shapes.isEmpty() ) {
        KoShapeLayer* layer = dynamic_cast<KoShapeLayer*>( shapes.last() );
        layer->addShape( path );
    }
}
예제 #13
0
void KoCreatePathTool::paintPath(KoPathShape& pathShape, QPainter &painter, const KoViewConverter &converter)
{
    Q_D(KoCreatePathTool);
    painter.setTransform(pathShape.absoluteTransformation(&converter) * painter.transform());
    painter.save();

    KoShapePaintingContext paintContext; //FIXME
    pathShape.paint(painter, converter, paintContext);
    painter.restore();
    if (pathShape.stroke()) {
        painter.save();
        pathShape.stroke()->paint(d->shape, painter, converter);
        painter.restore();
    }
}
예제 #14
0
void KoPathShapeLoaderPrivate::svgMoveTo(qreal x1, qreal y1, bool abs)
{
    if (abs)
        lastPoint = QPointF(x1, y1);
    else
        lastPoint += QPointF(x1, y1);
    path->moveTo(lastPoint);
}
void KoPathBreakAtPointCommand::undo()
{
    KUndo2Command::undo();
    KoPathShape * lastPathShape = 0;

    for (int i = 0; i < m_pointDataList.size(); ++i) {
        const KoPathPointData & pd = m_pointDataList.at(i);
        KoPathShape * pathShape = pd.pathShape;
        KoPathPointIndex pointIndex = pd.pointIndex;
        ++pointIndex.second;
        if (m_closedIndex.at(i).first != -1) {
            m_closedIndex[i] = pathShape->closeSubpath(m_closedIndex.at(i));
        } else {
            pointIndex.second = pointIndex.second + m_closedIndex.at(i).second;
            pathShape->join(pd.pointIndex.first);
        }
        m_points[i] = pathShape->removePoint(pointIndex);

        if (lastPathShape != pathShape) {
            if (lastPathShape) {
                lastPathShape->update();
            }
            lastPathShape = pathShape;
        }
    }
    if (lastPathShape) {
        lastPathShape->update();
    }

    m_deletePoints = true;
}
KoPathControlPointMoveCommand::KoPathControlPointMoveCommand(
    const KoPathPointData &pointData,
    const QPointF &offset,
    KoPathPoint::PointType pointType,
    KUndo2Command *parent)
        : KUndo2Command(parent)
        , m_pointData(pointData)
        , m_pointType(pointType)
{
    Q_ASSERT(offset.x() < 1e14 && offset.y() < 1e14);
    KoPathShape * pathShape = m_pointData.pathShape;
    KoPathPoint * point = pathShape->pointByIndex(m_pointData.pointIndex);
    if (point) {
        m_offset = point->parent()->documentToShape(offset) - point->parent()->documentToShape(QPointF(0, 0));
    }

    setText(i18nc("(qtundo-format)", "Move control point"));
}
예제 #17
0
void KoPathShapeLoaderPrivate::svgLineToVertical(qreal y, bool abs)
{
    if (abs)
        lastPoint.setY(y);
    else
        lastPoint.ry() += y;

    path->lineTo(lastPoint);
}
예제 #18
0
void KoPathShapeLoaderPrivate::svgLineToHorizontal(qreal x, bool abs)
{
    if (abs)
        lastPoint.setX(x);
    else
        lastPoint.rx() += x;

    path->lineTo(lastPoint);
}
void KoPathPointTypeCommand::undoChanges(const QList<PointData> &data)
{
    QList<PointData>::const_iterator it(data.begin());
    for (; it != data.end(); ++it) {
        KoPathShape *pathShape = it->m_pointData.pathShape;
        KoPathPoint *point = pathShape->pointByIndex(it->m_pointData.pointIndex);

        point->setProperties(it->m_oldProperties);
        if (it->m_hadControlPoint1)
            point->setControlPoint1(pathShape->documentToShape(it->m_oldControlPoint1));
        else
            point->removeControlPoint1();
        if (it->m_hadControlPoint2)
            point->setControlPoint2(pathShape->documentToShape(it->m_oldControlPoint2));
        else
            point->removeControlPoint2();
    }
}
void KoPathControlPointMoveCommand::redo()
{
    KUndo2Command::redo();
    KoPathShape * pathShape = m_pointData.pathShape;
    KoPathPoint * point = pathShape->pointByIndex(m_pointData.pointIndex);
    if (point) {
        pathShape->update();

        if (m_pointType == KoPathPoint::ControlPoint1) {
            point->setControlPoint1(point->controlPoint1() + m_offset);
            if (point->properties() & KoPathPoint::IsSymmetric) {
                // set the other control point so that it lies on the line between the moved
                // control point and the point, with the same distance to the point as the moved point
                point->setControlPoint2(2.0 * point->point() - point->controlPoint1());
            } else if (point->properties() & KoPathPoint::IsSmooth) {
                // move the other control point so that it lies on the line through point and control point
                // keeping its distance to the point
                QPointF direction = point->point() - point->controlPoint1();
                direction /= sqrt(direction.x() * direction.x() + direction.y() * direction.y());
                QPointF distance = point->point() - point->controlPoint2();
                qreal length = sqrt(distance.x() * distance.x() + distance.y() * distance.y());
                point->setControlPoint2(point->point() + length * direction);
            }
        } else if (m_pointType == KoPathPoint::ControlPoint2) {
            point->setControlPoint2(point->controlPoint2() + m_offset);
            if (point->properties() & KoPathPoint::IsSymmetric) {
                // set the other control point so that it lies on the line between the moved
                // control point and the point, with the same distance to the point as the moved point
                point->setControlPoint1(2.0 * point->point() - point->controlPoint2());
            } else if (point->properties() & KoPathPoint::IsSmooth) {
                // move the other control point so that it lies on the line through point and control point
                // keeping its distance to the point
                QPointF direction = point->point() - point->controlPoint2();
                direction /= sqrt(direction.x() * direction.x() + direction.y() * direction.y());
                QPointF distance = point->point() - point->controlPoint1();
                qreal length = sqrt(distance.x() * distance.x() + distance.y() * distance.y());
                point->setControlPoint1(point->point() + length * direction);
            }
        }

        pathShape->normalize();
        pathShape->update();
    }
}
void KoPathBreakAtPointCommand::redo()
{
    KUndo2Command::redo();
    KoPathPointData last(0, KoPathPointIndex(-1, -1));

    // offset, needed when path was opened
    int offset = 0;
    for (int i = m_pointDataList.size() - 1; i >= 0; --i) {
        const KoPathPointData & pd = m_pointDataList.at(i);
        KoPathShape * pathShape = pd.pathShape;

        KoPathPointIndex pointIndex = pd.pointIndex;
        if (last.pathShape != pathShape || last.pointIndex.first != pointIndex.first) {
            offset = 0;
        }

        pointIndex.second = pointIndex.second + offset + 1;
        pathShape->insertPoint(m_points[i], pointIndex);

        if (m_closedIndex.at(i).first != -1) {
            m_closedIndex[i] = pathShape->openSubpath(m_closedIndex.at(i));
            offset = m_closedIndex.at(i).second;
        } else {
            KoPathPointIndex breakIndex = pd.pointIndex;
            breakIndex.second += offset;
            pathShape->breakAfter(breakIndex);
            m_closedIndex[i].second = offset;
        }

        if (last.pathShape != pathShape) {
            if (last.pathShape) {
                last.pathShape->update();
            }
            last = pd;
        }
    }
    if (last.pathShape) {
        last.pathShape->update();
    }

    m_deletePoints = false;
}
/*
 * The algorithm to break a multiple open or closed subpaths is:
 * Subpath is closed
 * - open behind the last point in the subpath
 * - go on like as described in Not closed
 * Not closed
 * - break from the back of the subpath
 */
KoPathBreakAtPointCommand::KoPathBreakAtPointCommand(const QList<KoPathPointData> & pointDataList, KUndo2Command *parent)
        : KUndo2Command(parent)
        , m_deletePoints(true)
{
    QList<KoPathPointData> sortedPointDataList(pointDataList);
    qSort(sortedPointDataList);
    setText(i18nc("(qtundo-format)", "Break subpath at points"));

    QList<KoPathPointData>::const_iterator it(sortedPointDataList.constBegin());
    for (; it != sortedPointDataList.constEnd(); ++it) {
        KoPathShape * pathShape = it->pathShape;
        KoPathPoint * point = pathShape->pointByIndex(it->pointIndex);
        if(! point)
            continue;

        // check if subpath is closed and the point is start or end point of the subpath
        if(! pathShape->isClosedSubpath(it->pointIndex.first)) {
            if(it->pointIndex.second == 0
                || it->pointIndex.second == pathShape->subpathPointCount(it->pointIndex.first)) {
                continue;
            }
        }

        m_pointDataList.append(*it);
        m_points.push_back(new KoPathPoint(*point));
        m_closedIndex.push_back(KoPathPointIndex(-1, 0));
    }

    KoPathPointData last(0, KoPathPointIndex(-1, -1));
    for (int i = m_pointDataList.size() - 1; i >= 0; --i) {
        const KoPathPointData &current = m_pointDataList.at(i);

        if (last.pathShape != current.pathShape || last.pointIndex.first != current.pointIndex.first) {
            last = current;
            if (current.pathShape->isClosedSubpath(current.pointIndex.first)) {
                // the break will happen before the inserted point so we have to increment by 1
                m_closedIndex[i] = current.pointIndex;
                ++m_closedIndex[i].second;
            }
        }
    }
}
예제 #23
0
void KoShapeShadow::Private::paintShadow(KoShape *shape, QPainter &painter, const KoViewConverter &converter)
{
    QPainterPath path(shape->shadowOutline());
    if (!path.isEmpty()) {
        painter.save();
        KoShape::applyConversion(painter, converter);
        painter.setBrush(QBrush(color));

        // Make sure the shadow has the same fill rule as the shape.
        KoPathShape * pathShape = dynamic_cast<KoPathShape*>(shape);
        if (pathShape)
            path.setFillRule(pathShape->fillRule());

        painter.drawPath(path);
        painter.restore();
    }

    if (shape->stroke()) {
        shape->stroke()->paint(shape, painter, converter);
    }
}
예제 #24
0
void KoSubpathJoinCommand::redo()
{
    KUndo2Command::redo();
    KoPathShape * pathShape = m_pointData1.pathShape;

    bool closeSubpath = m_pointData1.pointIndex.first == m_pointData2.pointIndex.first;

    KoPathPoint * point1 = pathShape->pointByIndex(m_pointData1.pointIndex);
    KoPathPoint * point2 = pathShape->pointByIndex(m_pointData2.pointIndex);

    // if the endpoint is has a control point create a contol point for the new segment to be
    // at the symetric position to the exiting one
    if (m_reverse & ReverseFirst || closeSubpath) {
        if (point1->activeControlPoint2())
            point1->setControlPoint1(2.0 * point1->point() - point1->controlPoint2());
    } else if (point1->activeControlPoint1())
        point1->setControlPoint2(2.0 * point1->point() - point1->controlPoint1());
    if (m_reverse & ReverseSecond || closeSubpath) {
        if (point2->activeControlPoint1())
            point2->setControlPoint2(2.0 * point2->point() - point2->controlPoint1());
    } else if (point2->activeControlPoint2())
        point2->setControlPoint1(2.0 * point2->point() - point2->controlPoint2());

    if (closeSubpath) {
        pathShape->closeSubpath(m_pointData1.pointIndex);
    } else {
        if (m_reverse & ReverseFirst) {
            pathShape->reverseSubpath(m_pointData1.pointIndex.first);
        }
        if (m_reverse & ReverseSecond) {
            pathShape->reverseSubpath(m_pointData2.pointIndex.first);
        }
        pathShape->moveSubpath(m_pointData2.pointIndex.first, m_pointData1.pointIndex.first + 1);
        m_splitIndex = m_pointData1.pointIndex;
        m_splitIndex.second = pathShape->subpathPointCount(m_pointData1.pointIndex.first) - 1;
        pathShape->join(m_pointData1.pointIndex.first);
    }
    pathShape->normalize();
    pathShape->update();
}
예제 #25
0
KoPathPointInsertCommand::KoPathPointInsertCommand(const QList<KoPathPointData> & pointDataList, qreal insertPosition, QUndoCommand *parent)
        : QUndoCommand(parent)
        , m_deletePoints(true)
{
    if (insertPosition < 0)
        insertPosition = 0;
    if (insertPosition > 1)
        insertPosition = 1;

    //TODO the list needs to be sorted

    QList<KoPathPointData>::const_iterator it(pointDataList.begin());
    for (; it != pointDataList.end(); ++it) {
        KoPathShape * pathShape = it->pathShape;

        KoPathSegment segment = pathShape->segmentByIndex(it->pointIndex);

        // should not happen but to be sure
        if (! segment.isValid())
            continue;

        m_pointDataList.append(*it);
        
        QPair<KoPathSegment, KoPathSegment> splitSegments = segment.splitAt( insertPosition );
        
        KoPathPoint * split1 = splitSegments.first.second();
        KoPathPoint * split2 = splitSegments.second.first();
        KoPathPoint * splitPoint = new KoPathPoint( pathShape, split1->point() );
        if( split1->activeControlPoint1() )
            splitPoint->setControlPoint1(split1->controlPoint1());
        if( split2->activeControlPoint2() )
            splitPoint->setControlPoint2(split2->controlPoint2());
        
        m_points.append(splitPoint);
        QPointF cp1 = splitSegments.first.first()->controlPoint2();
        QPointF cp2 = splitSegments.second.second()->controlPoint1();
        m_controlPoints.append(QPair<QPointF, QPointF>(cp1, cp2));
    }
}
void KoPathSegmentTypeCommand::initialize(const QList<KoPathPointData> & pointDataList)
{
    QList<KoPathPointData>::const_iterator it(pointDataList.begin());
    for (; it != pointDataList.end(); ++it) {
        KoPathSegment segment = it->pathShape->segmentByIndex(it->pointIndex);
        if (segment.isValid()) {
            if (m_segmentType == Curve) {
                // don not change segment if already a curve
                if (segment.first()->activeControlPoint2() || segment.second()->activeControlPoint1())
                    continue;
            } else {
                // do not change segment if already a line
                if (! segment.first()->activeControlPoint2() && ! segment.second()->activeControlPoint1())
                    continue;
            }

            m_pointDataList.append(*it);
            SegmentTypeData segmentData;

            KoPathShape * pathShape = segment.first()->parent();

            // we are changing a curve to a line -> save control point positions
            if (m_segmentType == Line) {
                segmentData.m_controlPoint2 = pathShape->shapeToDocument(segment.first()->controlPoint2());
                segmentData.m_controlPoint1 = pathShape->shapeToDocument(segment.second()->controlPoint1());
            }
            // save point properties
            segmentData.m_properties2 = segment.first()->properties();
            segmentData.m_properties1 = segment.second()->properties();
            m_segmentData.append(segmentData);
        }
    }

    if (m_segmentType == Curve) {
        setText(i18nc("(qtundo-format)", "Change segments to curves"));
    } else {
        setText(i18nc("(qtundo-format)", "Change segments to lines"));
    }
}
예제 #27
0
KoPathShape * bezierFit(const QList<QPointF> &points, float error)
{
    FitVector tHat1, tHat2;

    tHat1 = ComputeLeftTangent(points, 0);
    tHat2 = ComputeRightTangent(points, points.count() - 1);

    int width = 0;
    QPointF *curve;
    curve = FitCubic(points, 0, points.count() - 1, tHat1, tHat2, error, width);

    KoPathShape * path = new KoPathShape();

    if (width > 3) {
        path->moveTo(curve[0]);
        path->curveTo(curve[1], curve[2], curve[3]);
        for (int i = 4; i < width; i += 4) {
            path->curveTo(curve[i+1], curve[i+2], curve[i+3]);
        }
    }

    delete[] curve;
    return path;
}
예제 #28
0
void KoPathShapeLoaderPrivate::svgCurveToCubic(qreal x1, qreal y1, qreal x2, qreal y2, qreal x, qreal y, bool abs)
{
    QPointF p1, p2;
    if (abs) {
        p1 = QPointF(x1, y1);
        p2 = QPointF(x2, y2);
        lastPoint = QPointF(x, y);
    } else {
        p1 = lastPoint + QPointF(x1, y1);
        p2 = lastPoint + QPointF(x2, y2);
        lastPoint += QPointF(x, y);
    }

    path->curveTo(p1, p2, lastPoint);
}
예제 #29
0
KoShape *KoPathShapeFactory::createDefaultShape(KoDocumentResourceManager *) const
{
    KoPathShape* path = new KoPathShape();
    path->moveTo(QPointF(0, 50));
    path->curveTo(QPointF(0, 120), QPointF(50, 120), QPointF(50, 50));
    path->curveTo(QPointF(50, -20), QPointF(100, -20), QPointF(100, 50));
    path->normalize();
    path->setStroke(new KoShapeStroke(1.0));
    return path;
}
예제 #30
0
void TestSnapStrategy::testExtensionSnap()
{
    //bool ExtensionSnapStrategy::snap(const QPointF &mousePosition, KoSnapProxy * proxy, qreal maxSnapDistance)
    ExtensionSnapStrategy toTest;
    const QPointF paramMousePos;
    MockShapeController fakeShapeControllerBase;
    MockCanvas fakeKoCanvasBase(&fakeShapeControllerBase);
    KoSnapGuide aKoSnapGuide(&fakeKoCanvasBase);
    KoSnapProxy paramProxy(&aKoSnapGuide);
    qreal paramSnapDistance = 0;
    bool didSnap = toTest.snap(paramMousePos, &paramProxy, paramSnapDistance);
    QVERIFY(!didSnap);

    //Second test case - testing the snap by providing ShapeManager with a shape that has snap points and a path
    //fakeShapeOne needs at least one subpath that is open in order to change the values of minDistances
    //which in turn opens the path where it is possible to get a true bool value back from the snap function
    // KoPathPointIndex openSubpath(const KoPathPointIndex &pointIndex); in KoPathShape needs to be called
    ExtensionSnapStrategy toTestTwo;
    const QPointF paramMousePosTwo;
    MockShapeController fakeShapeControllerBaseTwo;
    MockCanvas fakeKoCanvasBaseTwo(&fakeShapeControllerBaseTwo);
    KoShapeManager *fakeShapeManager = fakeKoCanvasBaseTwo.shapeManager();
    KoPathShape fakeShapeOne;
    QList<QPointF> firstSnapPointList;
    firstSnapPointList.push_back(QPointF(1,2));
    firstSnapPointList.push_back(QPointF(2,2));
    firstSnapPointList.push_back(QPointF(3,2));
    firstSnapPointList.push_back(QPointF(4,2));

    qreal paramSnapDistanceTwo = 4;
    fakeShapeOne.snapData().setSnapPoints(firstSnapPointList);
    fakeShapeOne.isVisible(true);

    QPointF firstPoint(0,2);
    QPointF secondPoint(1,2);
    QPointF thirdPoint(2,3);
    QPointF fourthPoint(3,4);

    fakeShapeOne.moveTo(firstPoint);
    fakeShapeOne.lineTo(secondPoint);
    fakeShapeOne.lineTo(thirdPoint);
    fakeShapeOne.lineTo(fourthPoint);

    fakeShapeManager->addShape(&fakeShapeOne);
    KoSnapGuide aKoSnapGuideTwo(&fakeKoCanvasBaseTwo);
    KoSnapProxy paramProxyTwo(&aKoSnapGuideTwo);

    bool didSnapTwo = toTest.snap(paramMousePosTwo, &paramProxyTwo, paramSnapDistanceTwo);
    QVERIFY(didSnapTwo);
}