예제 #1
0
void RGraphicsSceneQt::exportRay(const RRay& ray) {
    bool created = beginPath();

    Q_ASSERT(currentPainterPath.isValid());

    // find largest view box over all attached views:
    RBox box;
    QList<RGraphicsView*>::iterator it;
    for (it=views.begin(); it!=views.end(); it++) {
        RBox b = (*it)->getBox();
        box.growToIncludeBox(b);
    }

    // trim line to view box:
    RLine clippedLine = ray.getClippedLine(box);

    double offs = clippedLine.getStartPoint().getDistanceTo(ray.getBasePoint());
    if (RMath::isSameDirection(ray.getBasePoint().getAngleTo(clippedLine.getStartPoint()), ray.getDirection1())) {
        offs *= -1;
    }

    exportLine(clippedLine, offs);

    currentPainterPath.setAlwaysRegen(true);

    if (created) {
        endPath();
    }
}
예제 #2
0
void RGraphicsSceneQt::exportEllipse(const REllipse& ellipse, double offset) {
    bool created = beginPath();

    RGraphicsScene::exportEllipse(ellipse, offset);

    if (created) {
        endPath();
    }
}
예제 #3
0
void RGraphicsSceneQt::exportSpline(const RSpline& spline, double offset) {
    bool created = beginPath();

    RGraphicsScene::exportSpline(spline, offset);

    if (created) {
        endPath();
    }
}
예제 #4
0
void RGraphicsSceneQt::exportArc(const RArc& arc, double offset, double w1, double w2) {
    bool created = beginPath();

    RGraphicsScene::exportArc(arc, offset, w1, w2);

    if (created) {
        endPath();
    }
}
예제 #5
0
void RGraphicsSceneQt::exportPoint(const RPoint& point) {
    bool created = beginPath();

    currentPainterPath.addPoint(point.position);

    if (created) {
        endPath();
    }
}
예제 #6
0
void RGraphicsSceneQt::exportPolyline(const RPolyline& polyline, bool polylineGen, double offset) {
    // filling:
    bool created = beginPath();

    exportPolylineFill(polyline);

    if (created) {
        endPath();
    }

    // outline:
    created = beginPath();

    RGraphicsScene::exportPolyline(polyline, polylineGen, offset);

    if (created) {
        endPath();
    }
}
예제 #7
0
double RGraphicsSceneQt::exportLine(const RLine& line, double offset, double w1, double w2) {
    bool created = beginPath();

    bool ret = RGraphicsScene::exportLine(line, offset, w1, w2);

    if (created) {
        endPath();
    }

    return ret;
}
예제 #8
0
void RGraphicsSceneQt::exportThickArc(const RArc& arc, double w1, double w2) {
    if (RPolyline::hasProxy()) {
        bool hasCurrentPath = false;
        if (currentPainterPath.isValid()) {
            hasCurrentPath = true;
            endPath();
        }

        beginPath();

        RPolyline::getPolylineProxy()->exportThickArc(currentPainterPath, arc, w1, w2);
        currentPainterPath.setBrush(currentPen.color());
        currentPainterPath.setPen(QPen(Qt::NoPen));

        endPath();

        if (hasCurrentPath) {
            beginPath();
        }
    }
    else {
        exportArc(arc);
    }
}
예제 #9
0
void RGraphicsSceneQt::exportPolylineFill(const RPolyline& polyline) {
    if (currentBrush!=Qt::NoBrush) {
        bool created = beginPath();

        // TODO: support arc segments for filling:
        QPolygonF qpolygon;
        QList<RVector> points = polyline.getVertices();
        for (int i = 0; i < points.size(); ++i) {
            RVector v = points.at(i);
            qpolygon << QPointF(v.x, v.y);
        }
        currentPainterPath.setBrush(currentBrush);
        currentPainterPath.addPolygon(qpolygon);

        if (created) {
            endPath();
        }
    }
}
예제 #10
0
void KoCreatePathTool::mouseReleaseEvent(KoPointerEvent *event)
{
    Q_D(KoCreatePathTool);

    if (! d->shape || (event->buttons() & Qt::RightButton))
        return;

    d->listeningToModifiers = true; // After the first press-and-release
    d->repaintActivePoint();
    d->pointIsDragged = false;
    KoPathPoint *lastActivePoint = d->activePoint;

    if (!d->finishAfterThisPoint) {
        d->activePoint = d->shape->lineTo(event->point);
        canvas()->snapGuide()->setIgnoredPathPoints((QList<KoPathPoint*>()<<d->activePoint));
    }

    // apply symmetric point property if applicable
    if (lastActivePoint->activeControlPoint1() && lastActivePoint->activeControlPoint2()) {
        QPointF diff1 = lastActivePoint->point() - lastActivePoint->controlPoint1();
        QPointF diff2 = lastActivePoint->controlPoint2() - lastActivePoint->point();
        if (qFuzzyCompare(diff1.x(), diff2.x()) && qFuzzyCompare(diff1.y(), diff2.y()))
            lastActivePoint->setProperty(KoPathPoint::IsSymmetric);
    }

    if (d->finishAfterThisPoint) {

        d->firstPoint->setControlPoint1(d->activePoint->controlPoint1());
        delete d->shape->removePoint(d->shape->pathPointIndex(d->activePoint));
        d->activePoint = d->firstPoint;
        d->shape->closeMerge();

        // we are closing the path, so reset the existing start path point
        d->existingStartPoint = 0;
        // finish path
        endPath();
    }

    if (d->angleSnapStrategy && lastActivePoint->activeControlPoint2()) {
        d->angleSnapStrategy->deactivate();
    }
}
예제 #11
0
void KoCreatePathTool::mousePressEvent(KoPointerEvent *event)
{
    Q_D(KoCreatePathTool);

    //Right click removes last point
    if (event->button() == Qt::RightButton) {
      removeLastPoint();
      return;
    }

    const bool isOverFirstPoint = d->shape &&
        handleGrabRect(d->firstPoint->point()).contains(event->point);
    bool haveCloseModifier = (listeningToModifiers() && (event->modifiers() & Qt::ShiftModifier));

    if ((event->button() == Qt::LeftButton) && haveCloseModifier && !isOverFirstPoint) {
        endPathWithoutLastPoint();
        return;
    }

    d->finishAfterThisPoint = false;

    if (pathStarted()) {
        if (isOverFirstPoint) {
            d->activePoint->setPoint(d->firstPoint->point());
            canvas()->updateCanvas(d->shape->boundingRect());
            canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

            if (haveCloseModifier) {
                d->shape->closeMerge();
                // we are closing the path, so reset the existing start path point
                d->existingStartPoint = 0;
                // finish path
                endPath();
            } else {
                // the path shape will get closed when the user releases
                // the mouse button
                d->finishAfterThisPoint = true;
            }
        } else {
            canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

            QPointF point = canvas()->snapGuide()->snap(event->point, event->modifiers());

            // check whether we hit an start/end node of an existing path
            d->existingEndPoint = d->endPointAtPosition(point);
            if (d->existingEndPoint.isValid() && d->existingEndPoint != d->existingStartPoint) {
                point = d->existingEndPoint.path->shapeToDocument(d->existingEndPoint.point->point());
                d->activePoint->setPoint(point);
                // finish path
                endPath();
            } else {
                d->activePoint->setPoint(point);
                canvas()->updateCanvas(d->shape->boundingRect());
                canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
            }
        }
    } else {
        KoPathShape *pathShape = new KoPathShape();
        d->shape=pathShape;
        pathShape->setShapeId(KoPathShapeId);

        KoShapeStroke *stroke = new KoShapeStroke(canvas()->resourceManager()->activeStroke());
        stroke->setColor(canvas()->resourceManager()->foregroundColor().toQColor());

        pathShape->setStroke(stroke);
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());
        QPointF point = canvas()->snapGuide()->snap(event->point, event->modifiers());

        // check whether we hit an start/end node of an existing path
        d->existingStartPoint = d->endPointAtPosition(point);
        if (d->existingStartPoint.isValid()) {
            point = d->existingStartPoint.path->shapeToDocument(d->existingStartPoint.point->point());
        }
        d->activePoint = pathShape->moveTo(point);
        d->firstPoint = d->activePoint;
        canvas()->updateCanvas(handlePaintRect(point));
        canvas()->updateCanvas(canvas()->snapGuide()->boundingRect());

        canvas()->snapGuide()->setEditedShape(pathShape);

        d->angleSnapStrategy = new AngleSnapStrategy(d->angleSnappingDelta, d->angleSnapStatus);
        canvas()->snapGuide()->addCustomSnapStrategy(d->angleSnapStrategy);
    }

    if (d->angleSnapStrategy)
        d->angleSnapStrategy->setStartPoint(d->activePoint->point());
}
예제 #12
0
/* genEllipticPath:
 * Approximate an elliptical arc via Beziers of given degree
 * threshold indicates quality of approximation
 * if isSlice is true, the path begins and ends with line segments
 * to the center of the ellipse.
 * Returned path must be freed by the caller.
 */
static Ppolyline_t *genEllipticPath(ellipse_t * ep, int degree,
				    double threshold, boolean isSlice)
{
    double dEta;
    double etaB;
    double cosEtaB;
    double sinEtaB;
    double aCosEtaB;
    double bSinEtaB;
    double aSinEtaB;
    double bCosEtaB;
    double xB;
    double yB;
    double xBDot;
    double yBDot;
    double t;
    double alpha;
    Ppolyline_t *path = NEW(Ppolyline_t);

    // find the number of Bezier curves needed
    boolean found = FALSE;
    int i, n = 1;
    while ((!found) && (n < 1024)) {
	double dEta = (ep->eta2 - ep->eta1) / n;
	if (dEta <= 0.5 * M_PI) {
	    double etaB = ep->eta1;
	    found = TRUE;
	    for (i = 0; found && (i < n); ++i) {
		double etaA = etaB;
		etaB += dEta;
		found =
		    (estimateError(ep, degree, etaA, etaB) <= threshold);
	    }
	}
	n = n << 1;
    }

    dEta = (ep->eta2 - ep->eta1) / n;
    etaB = ep->eta1;

    cosEtaB = cos(etaB);
    sinEtaB = sin(etaB);
    aCosEtaB = ep->a * cosEtaB;
    bSinEtaB = ep->b * sinEtaB;
    aSinEtaB = ep->a * sinEtaB;
    bCosEtaB = ep->b * cosEtaB;
    xB = ep->cx + aCosEtaB * ep->cosTheta - bSinEtaB * ep->sinTheta;
    yB = ep->cy + aCosEtaB * ep->sinTheta + bSinEtaB * ep->cosTheta;
    xBDot = -aSinEtaB * ep->cosTheta - bCosEtaB * ep->sinTheta;
    yBDot = -aSinEtaB * ep->sinTheta + bCosEtaB * ep->cosTheta;

    if (isSlice) {
	moveTo(path, ep->cx, ep->cy);
	lineTo(path, xB, yB);
    } else {
	moveTo(path, xB, yB);
    }

    t = tan(0.5 * dEta);
    alpha = sin(dEta) * (sqrt(4 + 3 * t * t) - 1) / 3;

    for (i = 0; i < n; ++i) {

	double xA = xB;
	double yA = yB;
	double xADot = xBDot;
	double yADot = yBDot;

	etaB += dEta;
	cosEtaB = cos(etaB);
	sinEtaB = sin(etaB);
	aCosEtaB = ep->a * cosEtaB;
	bSinEtaB = ep->b * sinEtaB;
	aSinEtaB = ep->a * sinEtaB;
	bCosEtaB = ep->b * cosEtaB;
	xB = ep->cx + aCosEtaB * ep->cosTheta - bSinEtaB * ep->sinTheta;
	yB = ep->cy + aCosEtaB * ep->sinTheta + bSinEtaB * ep->cosTheta;
	xBDot = -aSinEtaB * ep->cosTheta - bCosEtaB * ep->sinTheta;
	yBDot = -aSinEtaB * ep->sinTheta + bCosEtaB * ep->cosTheta;

	if (degree == 1) {
	    lineTo(path, xB, yB);
#if DO_QUAD
	} else if (degree == 2) {
	    double k = (yBDot * (xB - xA) - xBDot * (yB - yA))
		/ (xADot * yBDot - yADot * xBDot);
	    quadTo(path, (xA + k * xADot), (yA + k * yADot), xB, yB);
#endif
	} else {
	    curveTo(path, (xA + alpha * xADot), (yA + alpha * yADot),
		    (xB - alpha * xBDot), (yB - alpha * yBDot), xB, yB);
	}

    }

    endPath(path, isSlice);

    return path;
}