Exemplo n.º 1
0
// This function returns the outermost intersection point between the path (a connector)
// and the item given.  If the item is a group, then the component items are considered.
// The transforms given should be to a common ancestor of both the path and item.
//
static bool try_get_intersect_point_with_item(SPPath* conn, SPItem* item,
        const Geom::Matrix& item_transform, const Geom::Matrix& conn_transform,
        const bool at_start, double& intersect_pos) {

    // Copy the curve and apply transformations up to common ancestor.
    SPCurve* conn_curve = conn->curve->copy();
    conn_curve->transform(conn_transform);

    Geom::PathVector conn_pv = conn_curve->get_pathvector();

    // If this is not the starting point, use Geom::Path::reverse() to reverse the path
    if (!at_start)
    {
        // connectors are actually a single path, so consider the first element from a Geom::PathVector
        conn_pv[0] = conn_pv[0].reverse();
    }

    // We start with the intersection point at the beginning of the path
    intersect_pos = 0.0;

    // Find the intersection.
    bool result = try_get_intersect_point_with_item_recursive(conn_pv, item, item_transform, intersect_pos);

    if (!result)
        // No intersection point has been found (why?)
        // just default to connector end
        intersect_pos = 0;
    // If not at the starting point, recompute position with respect to original path
    if (!at_start)
        intersect_pos = conn_pv[0].size() - intersect_pos;
    // Free the curve copy.
    conn_curve->unref();

    return result;
}
Exemplo n.º 2
0
static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_pv, SPItem* item,
        const Geom::Affine& item_transform, double& intersect_pos) {

    double initial_pos = intersect_pos;
    // if this is a group...
    if (SP_IS_GROUP(item)) {
        SPGroup* group = SP_GROUP(item);

        // consider all first-order children
        double child_pos = 0.0;
        std::vector<SPItem*> g = sp_item_group_item_list(group);
        for (std::vector<SPItem*>::const_iterator i = g.begin();i!=g.end();i++) {
            SPItem* child_item = *i;
            try_get_intersect_point_with_item_recursive(conn_pv, child_item,
                    item_transform * child_item->transform, child_pos);
            if (intersect_pos < child_pos)
                intersect_pos = child_pos;
        }
        return intersect_pos != initial_pos;
    }

    // if this is not a shape, nothing to be done
    if (!SP_IS_SHAPE(item)) return false;

    // make sure it has an associated curve
    SPCurve* item_curve = SP_SHAPE(item)->getCurve();
    if (!item_curve) return false;

    // apply transformations (up to common ancestor)
    item_curve->transform(item_transform);

    const Geom::PathVector& curve_pv = item_curve->get_pathvector();
    Geom::CrossingSet cross = crossings(conn_pv, curve_pv);
    // iterate over all Crossings
    //TODO: check correctness of the following code: inner loop uses loop variable
    //      with a name identical to the loop variable of the outer loop. Then rename.
    for (Geom::CrossingSet::const_iterator i = cross.begin(); i != cross.end(); ++i) {
        const Geom::Crossings& cr = *i;

        for (Geom::Crossings::const_iterator i = cr.begin(); i != cr.end(); ++i) {
            const Geom::Crossing& cr_pt = *i;
            if ( intersect_pos < cr_pt.ta)
                intersect_pos = cr_pt.ta;
        }
    }

    item_curve->unref();

    return intersect_pos != initial_pos;
}
Exemplo n.º 3
0
static bool try_get_intersect_point_with_item_recursive(Geom::PathVector& conn_pv, SPItem* item,
        const Geom::Matrix& item_transform, double& intersect_pos) {

    double initial_pos = intersect_pos;
    // if this is a group...
    if (SP_IS_GROUP(item)) {
        SPGroup* group = SP_GROUP(item);

        // consider all first-order children
        double child_pos = 0.0;
        for (GSList const* i = sp_item_group_item_list(group); i != NULL; i = i->next) {
            SPItem* child_item = SP_ITEM(i->data);
            try_get_intersect_point_with_item_recursive(conn_pv, child_item,
                    item_transform * child_item->transform, child_pos);
            if (intersect_pos < child_pos)
                intersect_pos = child_pos;
        }
        return intersect_pos != initial_pos;
    }

    // if this is not a shape, nothing to be done
    if (!SP_IS_SHAPE(item)) return false;

    // make sure it has an associated curve
    SPCurve* item_curve = sp_shape_get_curve(SP_SHAPE(item));
    if (!item_curve) return false;

    // apply transformations (up to common ancestor)
    item_curve->transform(item_transform);

    const Geom::PathVector& curve_pv = item_curve->get_pathvector();
    Geom::CrossingSet cross = crossings(conn_pv, curve_pv);
    // iterate over all Crossings
    for (Geom::CrossingSet::const_iterator i = cross.begin(); i != cross.end(); i++) {
        const Geom::Crossings& cr = *i;

        for (Geom::Crossings::const_iterator i = cr.begin(); i != cr.end(); i++) {
            const Geom::Crossing& cr_pt = *i;
            if ( intersect_pos < cr_pt.ta)
                intersect_pos = cr_pt.ta;
        }
    }

    item_curve->unref();

    return intersect_pos != initial_pos;
}