/**
 * Computes a point on the offset;  used to set a "seed" position for
 * the control knot.
 *
 * \return the topmost point on the offset.
 */
void
sp_offset_top_point (SPOffset const * offset, Geom::Point *px)
{
    (*px) = Geom::Point(0, 0);

    if (offset == NULL) {
        return;
    }

    if (offset->knotSet)
    {
        (*px) = offset->knot;
        return;
    }

    SPCurve *curve = SP_SHAPE (offset)->getCurve();

    if (curve == NULL)
    {
        // CPPIFY
        //offset->set_shape();
        const_cast<SPOffset*>(offset)->set_shape();

        curve = SP_SHAPE (offset)->getCurve();

        if (curve == NULL)
            return;
    }

    if (curve->is_empty())
    {
        curve->unref();
        return;
    }

    Path *finalPath = new Path;
    finalPath->LoadPathVector(curve->get_pathvector());

    Shape *theShape = new Shape;

    finalPath->Convert (1.0);
    finalPath->Fill (theShape, 0);

    if (theShape->hasPoints())
    {
        theShape->SortPoints ();
        *px = theShape->getPoint(0).x;
    }

    delete theShape;
    delete finalPath;
    curve->unref();
}
static void
refresh_offset_source(SPOffset* offset)
{
    if ( offset == NULL ) {
        return;
    }

    offset->sourceDirty=false;

    // le mauvais cas: pas d'attribut d => il faut verifier que c'est une SPShape puis prendre le contour
    // The bad case: no d attribute.  Must check that it's an SPShape and then take the outline.
    SPObject *refobj=offset->sourceObject;

    if ( refobj == NULL ) {
        return;
    }

    SPItem  *item  = SP_ITEM (refobj);
    SPCurve *curve = NULL;

    if (SP_IS_SHAPE (item)) {
        curve = SP_SHAPE (item)->getCurve ();
    }
    else if (SP_IS_TEXT (item)) {
        curve = SP_TEXT (item)->getNormalizedBpath ();
    }
    else {
        return;
    }

    if (curve == NULL) {
        return;
    }

    Path *orig = new Path;
    orig->LoadPathVector(curve->get_pathvector());
    curve->unref();

    if (!item->transform.isIdentity()) {
        gchar const *t_attr = item->getRepr()->attribute("transform");

        if (t_attr) {
            Geom::Affine t;

            if (sp_svg_transform_read(t_attr, &t)) {
                orig->Transform(t);
            }
        }
    }

    // Finish up.
    {
        SPCSSAttr *css;
        const gchar *val;
        Shape *theShape = new Shape;
        Shape *theRes = new Shape;

        orig->ConvertWithBackData (1.0);
        orig->Fill (theShape, 0);

        css = sp_repr_css_attr (offset->sourceRepr , "style");
        val = sp_repr_css_property (css, "fill-rule", NULL);

        if (val && strcmp (val, "nonzero") == 0)
        {
            theRes->ConvertToShape (theShape, fill_nonZero);
        }
        else if (val && strcmp (val, "evenodd") == 0)
        {
            theRes->ConvertToShape (theShape, fill_oddEven);
        }
        else
        {
            theRes->ConvertToShape (theShape, fill_nonZero);
        }

        Path *originaux[1];
        originaux[0] = orig;
        Path *res = new Path;
        theRes->ConvertToForme (res, 1, originaux);

        delete theShape;
        delete theRes;

        char *res_d = res->svg_dump_path ();
        delete res;
        delete orig;

        // TODO fix:
        //XML Tree being used diectly here while it shouldn't be.
        offset->getRepr()->setAttribute("inkscape:original", res_d);

        free (res_d);
    }
}