Logo Search packages:      
Sourcecode: inkscape version File versions  Download package

static SPGradient* chase_hrefs ( SPGradient *const   src,
bool(*)(SPGradient const *)  match 
) [static]

Returns the first of {src, src->ref->getObject(), src->ref->getObject()->ref->getObject(),...} for which match is true, or NULL if none found.

The raison d'ĂȘtre of this routine is that it correctly handles cycles in the href chain (e.g., if a gradient gives itself as its href, or if each of two gradients gives the other as its href).

Precondition:
SP_IS_GRADIENT(src).

Definition at line 834 of file sp-gradient.cpp.

References SPGradientReference::getObject(), and SPGradient::ref.

Referenced by SPGradient::fetchSpread(), SPGradient::fetchUnits(), and SPGradient::getVector().

{
    g_return_val_if_fail(SP_IS_GRADIENT(src), NULL);

    /* Use a pair of pointers for detecting loops: p1 advances half as fast as p2.  If there is a
       loop, then once p1 has entered the loop, we'll detect it the next time the distance between
       p1 and p2 is a multiple of the loop size. */
    SPGradient *p1 = src, *p2 = src;
    bool do1 = false;
    for (;;) {
        if (match(p2)) {
            return p2;
        }

        p2 = p2->ref->getObject();
        if (!p2) {
            return p2;
        }
        if (do1) {
            p1 = p1->ref->getObject();
        }
        do1 = !do1;

        if ( p2 == p1 ) {
            /* We've been here before, so return NULL to indicate that no matching gradient found
             * in the chain. */
            return NULL;
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Generated by  Doxygen 1.6.0   Back to index