Beispiel #1
0
/*
 * Converts all segments in all paths to Geom::LineSegment or Geom::HLineSegment or
 * Geom::VLineSegment or Geom::CubicBezier.
 */
Geom::PathVector
pathv_to_linear_and_cubic_beziers( Geom::PathVector const &pathv )
{
    Geom::PathVector output;

    for (Geom::PathVector::const_iterator pit = pathv.begin(); pit != pathv.end(); ++pit) {
        output.push_back( Geom::Path() );
        output.back().start( pit->initialPoint() );
        output.back().close( pit->closed() );

        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
            if (is_straight_curve(*cit)) {
                Geom::LineSegment l(cit->initialPoint(), cit->finalPoint());
                output.back().append(l);
            } else {
                Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit);
                if (curve && curve->order() == 3) {
                    Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]);
                    output.back().append(b);
                } else {
                    // convert all other curve types to cubicbeziers
                    Geom::Path cubicbezier_path = Geom::cubicbezierpath_from_sbasis(cit->toSBasis(), 0.1);
                    output.back().append(cubicbezier_path);
                }
            }
        }
    }
    
    return output;
}
// FIXME: why is 'transform' argument not used?
void
PrintLatex::print_pathvector(SVGOStringStream &os, Geom::PathVector const &pathv_in, const Geom::Affine & /*transform*/)
{
    if (pathv_in.empty())
        return;

//    Geom::Affine tf=transform;   // why was this here?
    Geom::Affine tf_stack=m_tr_stack.top(); // and why is transform argument not used?
    Geom::PathVector pathv = pathv_in * tf_stack; // generates new path, which is a bit slow, but this doesn't have to be performance optimized

    os << "\\newpath\n";

    for(Geom::PathVector::const_iterator it = pathv.begin(); it != pathv.end(); ++it) {

        os << "\\moveto(" << it->initialPoint()[Geom::X] << "," << it->initialPoint()[Geom::Y] << ")\n";

        for(Geom::Path::const_iterator cit = it->begin(); cit != it->end_open(); ++cit) {
            print_2geomcurve(os, *cit);
        }

        if (it->closed()) {
            os << "\\closepath\n";
        }

    }
}
Beispiel #3
0
/*
 * Returns the number of segments of all paths summed
 * This count includes the closing line segment of a closed path.
 */
guint
SPCurve::get_segment_count() const
{
    guint nr = 0;
    for(Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) {
        nr += (*it).size();

        if (it->closed())   nr += 1;
    }
    return nr;
}
Beispiel #4
0
/*
 * Converts all segments in all paths to Geom::LineSegment.  There is an intermediate
 * stage where some may be converted to beziers.  maxdisp is the maximum displacement from
 * the line segment to the bezier curve; ** maxdisp is not used at this moment **.
 *
 * This is NOT a terribly fast method, but it should give a solution close to the one with the
 * fewest points.
 */
Geom::PathVector
pathv_to_linear( Geom::PathVector const &pathv, double /*maxdisp*/)
{
    Geom::PathVector output;
    Geom::PathVector tmppath = pathv_to_linear_and_cubic_beziers(pathv);
    
    // Now all path segments are either already lines, or they are beziers.

    for (Geom::PathVector::const_iterator pit = tmppath.begin(); pit != tmppath.end(); ++pit) {
        output.push_back( Geom::Path() );
        output.back().start( pit->initialPoint() );
        output.back().close( pit->closed() );

        for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
            if (is_straight_curve(*cit)) {
                Geom::LineSegment ls(cit->initialPoint(), cit->finalPoint());
                output.back().append(ls);
            } 
            else { /* all others must be Bezier curves */
                Geom::BezierCurve const *curve = dynamic_cast<Geom::BezierCurve const *>(&*cit);
                Geom::CubicBezier b((*curve)[0], (*curve)[1], (*curve)[2], (*curve)[3]);
                std::vector<Geom::Point> bzrpoints = b.points();
                Geom::Point A = bzrpoints[0];
                Geom::Point B = bzrpoints[1];
                Geom::Point C = bzrpoints[2];
                Geom::Point D = bzrpoints[3];
                std::vector<Geom::Point> pointlist;
                pointlist.push_back(A);
                recursive_bezier4(
                   A[X], A[Y], 
                   B[X], B[Y], 
                   C[X], C[Y], 
                   D[X], D[Y],
                   pointlist, 
                   0);
                pointlist.push_back(D);
                Geom::Point r1 = pointlist[0];
                for (unsigned int i=1; i<pointlist.size();i++){
                   Geom::Point prev_r1 = r1;
                   r1 = pointlist[i];
                   Geom::LineSegment ls(prev_r1, r1);
                   output.back().append(ls);
                }
                pointlist.clear();
           }
        }
    }
    
    return output;
}
Beispiel #5
0
/**
 * True iff all subpaths are closed.
 * Returns false if the curve is empty.
 */
bool
SPCurve::is_closed() const
{
    if (is_empty()) {
        return false;
    } else {
        bool closed = true;
        for (Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) {
            if ( ! it->closed() ) {
                closed = false;
                break;
            }
        }
        return closed;
    }
}
Beispiel #6
0
/**
 * returns the number of nodes in a path, used for statusbar text when selecting an spcurve.
 * Sum of nodes in all the paths. When a path is closed, and its closing line segment is of zero-length,
 * this function will not count the closing knot double (so basically ignores the closing line segment when it has zero length)
 */
guint
SPCurve::nodes_in_path() const
{
    guint nr = 0;
    for(Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) {
        nr += (*it).size();

        nr++; // count last node (this works also for closed paths because although they don't have a 'last node', they do have an extra segment

        // do not count closing knot double for zero-length closing line segments
        // however, if the path is only a moveto, and is closed, do not subtract 1 (otherwise the result will be zero nodes)
        if ( it->closed()
                && ((*it).size() != 0) )
        {
            Geom::Curve const &c = it->back_closed();
            if (are_near(c.initialPoint(), c.finalPoint())) {
                nr--;
            }
        }
    }

    return nr;
}