コード例 #1
0
/**
Returns the topmost non-layer group from the descendants of group which is at point
p, or NULL if none. Recurses into layers but not into groups.
 */
SPItem*
find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Point const p)
{
    SPItem *seen = NULL;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);

    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
        if (!SP_IS_ITEM(o)) continue;
        if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER) {
            SPItem *newseen = find_group_at_point(dkey, SP_GROUP(o), p);
            if (newseen) {
                seen = newseen;
            }
        }
        if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) {
            SPItem *child = SP_ITEM(o);
            NRArenaItem *arenaitem = sp_item_get_arenaitem(child, dkey);

            // seen remembers the last (topmost) of groups pickable at this point
            if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL) {
                seen = child;
            }
        }
    }
    return seen;
}
コード例 #2
0
/**
Returns the bottommost item from the list which is at the point, or NULL if none.
*/
SPItem*
sp_document_item_from_list_at_point_bottom(unsigned int dkey, SPGroup *group, GSList const *list,
                                           Geom::Point const p, bool take_insensitive)
{
    g_return_val_if_fail(group, NULL);
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);

    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {

        if (!SP_IS_ITEM(o)) continue;

        SPItem *item = SP_ITEM(o);
        NRArenaItem *arenaitem = sp_item_get_arenaitem(item, dkey);
        if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL
            && (take_insensitive || item->isVisibleAndUnlocked(dkey))) {
            if (g_slist_find((GSList *) list, item) != NULL)
                return item;
        }

        if (SP_IS_GROUP(o)) {
            SPItem *found = sp_document_item_from_list_at_point_bottom(dkey, SP_GROUP(o), list, p, take_insensitive);
            if (found)
                return found;
        }

    }
    return NULL;
}
コード例 #3
0
/**
Returns the topmost (in z-order) item from the descendants of group (recursively) which
is at the point p, or NULL if none. Honors into_groups on whether to recurse into
non-layer groups or not. Honors take_insensitive on whether to return insensitive
items. If upto != NULL, then if item upto is encountered (at any level), stops searching
upwards in z-order and returns what it has found so far (i.e. the found item is
guaranteed to be lower than upto).
 */
SPItem*
find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL)
{
    SPItem *seen = NULL, *newseen = NULL;
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);

    for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) {
        if (!SP_IS_ITEM(o)) continue;

        if (upto && SP_ITEM(o) == upto)
            break;

        if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) {
            // if nothing found yet, recurse into the group
            newseen = find_item_at_point(dkey, SP_GROUP(o), p, into_groups, take_insensitive, upto);
            if (newseen) {
                seen = newseen;
                newseen = NULL;
            }

            if (item_is_in_group(upto, SP_GROUP(o)))
                break;

        } else {
            SPItem *child = SP_ITEM(o);
            NRArenaItem *arenaitem = sp_item_get_arenaitem(child, dkey);

            // seen remembers the last (topmost) of items pickable at this point
            if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL
                && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
                seen = child;
            }
        }
    }
    return seen;
}
コード例 #4
0
/**
 * Process a GdkPixbuf, according to which areas have been
 * obscured in the GUI.
 */
Glib::RefPtr<Gdk::Pixbuf>
Tracer::sioxProcessImage(SPImage *img,
             Glib::RefPtr<Gdk::Pixbuf>origPixbuf)
{
    if (!sioxEnabled)
        return origPixbuf;

    if (origPixbuf == lastOrigPixbuf)
        return lastSioxPixbuf;

    //g_message("siox: start");

    //Convert from gdk, so a format we know.  By design, the pixel
    //format in PackedPixelMap is identical to what is needed by SIOX
    SioxImage simage(origPixbuf->gobj());

    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
    if (!desktop)
        {
        g_warning(_("Trace: No active desktop"));
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    Inkscape::MessageStack *msgStack = sp_desktop_message_stack(desktop);

    Inkscape::Selection *sel = sp_desktop_selection(desktop);
    if (!sel)
        {
        char *msg = _("Select an <b>image</b> to trace");
        msgStack->flash(Inkscape::ERROR_MESSAGE, msg);
        //g_warning(msg);
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    NRArenaItem *aImg = sp_item_get_arenaitem(img, desktop->dkey);
    //g_message("img: %d %d %d %d\n", aImg->bbox.x0, aImg->bbox.y0,
    //                                aImg->bbox.x1, aImg->bbox.y1);

    double width  = (double)(aImg->bbox.x1 - aImg->bbox.x0);
    double height = (double)(aImg->bbox.y1 - aImg->bbox.y0);

    double iwidth  = (double)simage.getWidth();
    double iheight = (double)simage.getHeight();

    double iwscale = width  / iwidth;
    double ihscale = height / iheight;

    std::vector<NRArenaItem *> arenaItems;
    std::vector<SPShape *>::iterator iter;
    for (iter = sioxShapes.begin() ; iter!=sioxShapes.end() ; iter++)
        {
        SPItem *item = *iter;
        NRArenaItem *aItem = sp_item_get_arenaitem(item, desktop->dkey);
        arenaItems.push_back(aItem);
        }

    //g_message("%d arena items\n", arenaItems.size());

    //PackedPixelMap *dumpMap = PackedPixelMapCreate(
    //                simage.getWidth(), simage.getHeight());

    //g_message("siox: start selection");

    for (int row=0 ; row<iheight ; row++)
        {
        double ypos = ((double)aImg->bbox.y0) + ihscale * (double) row;
        for (int col=0 ; col<simage.getWidth() ; col++)
            {
            //Get absolute X,Y position
            double xpos = ((double)aImg->bbox.x0) + iwscale * (double)col;
            Geom::Point point(xpos, ypos);
            point *= *aImg->transform;
            //point *= imgMat;
            //point = desktop->doc2dt(point);
            //g_message("x:%f    y:%f\n", point[0], point[1]);
            bool weHaveAHit = false;
            std::vector<NRArenaItem *>::iterator aIter;
            for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
                {
                NRArenaItem *arenaItem = *aIter;
                NRArenaItemClass *arenaClass =
                    (NRArenaItemClass *) NR_OBJECT_GET_CLASS (arenaItem);
                if (arenaClass->pick(arenaItem, point, 1.0f, 1))
                    {
                    weHaveAHit = true;
                    break;
                    }
                }

            if (weHaveAHit)
                {
                //g_message("hit!\n");
                //dumpMap->setPixelLong(dumpMap, col, row, 0L);
                simage.setConfidence(col, row,
                        Siox::UNKNOWN_REGION_CONFIDENCE);
                }
            else
                {
                //g_message("miss!\n");
                //dumpMap->setPixelLong(dumpMap, col, row,
                //        simage.getPixel(col, row));
                simage.setConfidence(col, row,
                        Siox::CERTAIN_BACKGROUND_CONFIDENCE);
                }
            }
        }

    //g_message("siox: selection done");

    //dumpMap->writePPM(dumpMap, "siox1.ppm");
    //dumpMap->destroy(dumpMap);

    //## ok we have our pixel buf
    TraceSioxObserver observer(this);
    Siox sengine(&observer);
    SioxImage result = sengine.extractForeground(simage, 0xffffff);
    if (!result.isValid())
        {
        g_warning(_("Invalid SIOX result"));
        return Glib::RefPtr<Gdk::Pixbuf>(NULL);
        }

    //result.writePPM("siox2.ppm");

    /* Free Arena and ArenaItem */
    /*
    std::vector<NRArenaItem *>::iterator aIter;
    for (aIter = arenaItems.begin() ; aIter!=arenaItems.end() ; aIter++)
       {
       NRArenaItem *arenaItem = *aIter;
       nr_arena_item_unref(arenaItem);
       }
    nr_object_unref((NRObject *) arena);
    */

    Glib::RefPtr<Gdk::Pixbuf> newPixbuf = Glib::wrap(result.getGdkPixbuf());

    //g_message("siox: done");

    lastSioxPixbuf = newPixbuf;

    return newPixbuf;
}