Exemplo n.º 1
0
static void
spdc_pen_set_point (SPPenContext *pc, NRPointF *p, guint state)
{
	SPDrawContext *dc;

	dc = SP_DRAW_CONTEXT (pc);

	if (dc->npoints == 0) {
		/* Just set initial point */
		dc->p[0] = *p;
		dc->p[1] = *p;
		dc->npoints = 2;
		sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);
	} else {
		dc->p[2] = *p;
		dc->p[3] = *p;
		dc->p[4] = *p;
		dc->npoints = 5;
		sp_curve_reset (dc->red_curve);
		sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y);
		if ((pc->onlycurves) ||
		    (dc->p[1].x != dc->p[0].x) ||
		    (dc->p[1].y != dc->p[0].y)) {
			sp_curve_curveto (dc->red_curve, dc->p[1].x, dc->p[1].y, dc->p[2].x, dc->p[2].y, dc->p[3].x, dc->p[3].y);
		} else {
			sp_curve_lineto (dc->red_curve, dc->p[3].x, dc->p[3].y);
		}
		sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve);
	}
}
static void sp_dropper_context_setup(SPEventContext *ec)
{
    SPDropperContext *dc = SP_DROPPER_CONTEXT(ec);

    if (((SPEventContextClass *) parent_class)->setup) {
        ((SPEventContextClass *) parent_class)->setup(ec);
    }

    /* TODO: have a look at sp_dyna_draw_context_setup where the same is done.. generalize? at least make it an arcto! */
    SPCurve *c = new SPCurve();
    const double C1 = 0.552;
    c->moveto(-1,0);
    c->curveto(-1, C1, -C1, 1, 0, 1 );
    c->curveto(C1, 1, 1, C1, 1, 0 );
    c->curveto(1, -C1, C1, -1, 0, -1 );
    c->curveto(-C1, -1, -1, -C1, -1, 0 );
    c->closepath();
    dc->area = sp_canvas_bpath_new(sp_desktop_controls(ec->desktop), c);
    c->unref();
    sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(dc->area), 0x00000000,(SPWindRule)0);
    sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->area), 0x0000007f, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
    sp_canvas_item_hide(dc->area);

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    if (prefs->getBool("/tools/dropper/selcue")) {
        ec->enableSelectionCue();
    }

    if (prefs->getBool("/tools/dropper/gradientdrag")) {
        ec->enableGrDrag();
    }
}
Exemplo n.º 3
0
static void
fit_and_split(SPPencilContext *pc)
{
    g_assert( pc->npoints > 1 );

    double const tolerance_sq = 0;

    Geom::Point b[4];
    g_assert(is_zero(pc->req_tangent)
             || is_unit_vector(pc->req_tangent));
    Geom::Point const tHatEnd(0, 0);
    int const n_segs = Geom::bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints,
                                                pc->req_tangent, tHatEnd, 
                                                tolerance_sq, 1);
    if ( n_segs > 0
         && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) )
    {
        /* Fit and draw and reset state */
        pc->red_curve->reset();
        pc->red_curve->moveto(b[0]);
        pc->red_curve->curveto(b[1], b[2], b[3]);
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
        pc->red_curve_is_valid = true;
    } else {
        /* Fit and draw and copy last point */

        g_assert(!pc->red_curve->is_empty());

        /* Set up direction of next curve. */
        {
            Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->red_curve->last_segment());
            g_assert( last_seg );      // Relevance: validity of (*last_seg)[2]
            pc->p[0] = last_seg->finalPoint();
            pc->npoints = 1;
            Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] );
            pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
                                ? Geom::Point(0, 0)
                                : Geom::unit_vector(req_vec) );
        }

        pc->green_curve->append_continuous(pc->red_curve, 0.0625);
        SPCurve *curve = pc->red_curve->copy();

        /// \todo fixme:
        SPCanvasItem *cshape = sp_canvas_bpath_new(sp_desktop_sketch(pc->desktop), curve);
        curve->unref();
        sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);

        pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape);

        pc->red_curve_is_valid = false;
    }
}
Exemplo n.º 4
0
static void sp_canvas_bpath_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags)
{
    SPCanvasBPath *cbp = SP_CANVAS_BPATH(item);

    item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2);

    if (reinterpret_cast<SPCanvasItemClass *>(sp_canvas_bpath_parent_class)->update) {
        reinterpret_cast<SPCanvasItemClass *>(sp_canvas_bpath_parent_class)->update(item, affine, flags);
    }

    sp_canvas_item_reset_bounds (item);

    if (!cbp->curve) return;

    cbp->affine = affine;

    Geom::OptRect bbox = bounds_exact_transformed(cbp->curve->get_pathvector(), affine);

    if (bbox) {
        item->x1 = (int)bbox->min()[Geom::X] - 1;
        item->y1 = (int)bbox->min()[Geom::Y] - 1;
        item->x2 = (int)bbox->max()[Geom::X] + 1;
        item->y2 = (int)bbox->max()[Geom::Y] + 1;
    } else {
        item->x1 = 0;
        item->y1 = 0;
        item->x2 = 0;
        item->y2 = 0;
    }
    item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2);
}
Exemplo n.º 5
0
static void
pencil_cancel (SPPencilContext *const pc) 
{
    if (pc->grab) {
        /* Release grab now */
        sp_canvas_item_ungrab(pc->grab, 0);
        pc->grab = NULL;
    }

    pc->is_drawing = false;

    pc->state = SP_PENCIL_CONTEXT_IDLE;

    pc->red_curve->reset();
    sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
    while (pc->green_bpaths) {
        gtk_object_destroy(GTK_OBJECT(pc->green_bpaths->data));
        pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data);
    }
    pc->green_curve->reset();
    if (pc->green_anchor) {
        pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor);
    }

    pc->_message_context->clear();
    pc->_message_context->flash(Inkscape::NORMAL_MESSAGE, _("Drawing cancelled"));

    sp_canvas_end_forced_full_redraws(pc->desktop->canvas);
}
Exemplo n.º 6
0
/**
 * Change moving endpoint position.
 * <ul>
 * <li>Ctrl constrains to moving to H/V direction, snapping in given direction.
 * <li>Otherwise we snap freely to whatever attractors are available.
 * </ul>
 *
 * Number of points is (re)set to 2 always, 2nd point is modified.
 * We change RED curve.
 */
static void
spdc_set_endpoint(SPPencilContext *const pc, Geom::Point const p)
{
    if (pc->npoints == 0) {
        return;
        /* May occur if first point wasn't in SVG plane (e.g. weird w2d transform, perhaps from bad
         * zoom setting).
         */
    }
    g_return_if_fail( pc->npoints > 0 );

    pc->red_curve->reset();
    if ( ( p == pc->p[0] )
         || !in_svg_plane(p) )
    {
        pc->npoints = 1;
    } else {
        pc->p[1] = p;
        pc->npoints = 2;

        pc->red_curve->moveto(pc->p[0]);
        pc->red_curve->lineto(pc->p[1]);
        pc->red_curve_is_valid = true;

        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve);
    }
}
Exemplo n.º 7
0
static void
interpolate(SPPencilContext *pc)
{

    g_assert( pc->ps.size() > 1 );

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
    double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() * 
                                               tol) * exp(0.2*tol - 2);

    g_assert(is_zero(pc->req_tangent)
             || is_unit_vector(pc->req_tangent));
    Geom::Point const tHatEnd(0, 0);

    guint n_points  = pc->ps.size();
    pc->green_curve->reset();
    pc->red_curve->reset();
    pc->red_curve_is_valid = false;

    Geom::Point * b = g_new(Geom::Point, 4*n_points);
    Geom::Point * points = g_new(Geom::Point, 4*n_points);
    for (unsigned int i = 0; i < pc->ps.size(); i++) { 
        points[i] = pc->ps[i];
    }

    // worst case gives us a segment per point
    int max_segs = 4*n_points;

    int const n_segs = Geom::bezier_fit_cubic_r(b, points, n_points,
                                             tolerance_sq, max_segs);

    if ( n_segs > 0)
    {
        /* Fit and draw and reset state */
        pc->green_curve->moveto(b[0]);
        for (int c = 0; c < n_segs; c++) { 
            pc->green_curve->curveto(b[4*c+1], b[4*c+2], b[4*c+3]);
        }
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);

        /* Fit and draw and copy last point */
        g_assert(!pc->green_curve->is_empty());

        /* Set up direction of next curve. */
        {
            Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->green_curve->last_segment());
            g_assert( last_seg );      // Relevance: validity of (*last_seg)[2]
            pc->p[0] = last_seg->finalPoint();
            pc->npoints = 1;
            Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] );
            pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
                                ? Geom::Point(0, 0)
                                : Geom::unit_vector(req_vec) );
        }
    }
    g_free(b);
    g_free(points);
    pc->ps.clear();
}
Exemplo n.º 8
0
static void
spdc_pen_finish_segment (SPPenContext *pc, NRPointF *p, guint state)
{
	SPDrawContext *dc;

	dc = SP_DRAW_CONTEXT (pc);

	if (!sp_curve_empty (dc->red_curve)) {
		SPCurve *curve;
		SPCanvasItem *cshape;

		sp_curve_append_continuous (dc->green_curve, dc->red_curve, 0.0625);
		curve = sp_curve_copy (dc->red_curve);
		/* fixme: */
		cshape = sp_canvas_bpath_new (SP_DT_SKETCH (SP_EVENT_CONTEXT (dc)->desktop), curve);
		sp_curve_unref (curve);
		sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (cshape), dc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);

		dc->green_bpaths = g_slist_prepend (dc->green_bpaths, cshape);

		dc->p[0] = dc->p[3];
		dc->p[1] = dc->p[4];
		dc->npoints = 2;

		sp_curve_reset (dc->red_curve);
	}
}
Exemplo n.º 9
0
void Inkscape::Rubberband::move(Geom::Point const &p)
{
    if (!_started) 
        return;

    _end = p;
    _desktop->scroll_to_point(p);
    _touchpath_curve->lineto(p);

    Geom::Point next = _desktop->d2w(p);
    // we want the points to be at most 0.5 screen pixels apart,
    // so that we don't lose anything small;
    // if they are farther apart, we interpolate more points
    if (_points.size() > 0 && Geom::L2(next-_points.back()) > 0.5) {
        Geom::Point prev = _points.back();
        int subdiv = 2 * (int) round(Geom::L2(next-prev) + 0.5);
        for (int i = 1; i <= subdiv; i ++) {
            _points.push_back(prev + ((double)i/subdiv) * (next - prev));
        }
    } else {
        _points.push_back(next);
    }

    if (_mode == RUBBERBAND_MODE_RECT) {
        if (_rect == NULL) {
            _rect = static_cast<CtrlRect *>(sp_canvas_item_new(sp_desktop_controls(_desktop), SP_TYPE_CTRLRECT, NULL));
        }
        _rect->setRectangle(Geom::Rect(_start, _end));

        sp_canvas_item_show(_rect);
        if (_touchpath)
            sp_canvas_item_hide(_touchpath);

    } else if (_mode == RUBBERBAND_MODE_TOUCHPATH) {
        if (_touchpath == NULL) {
            _touchpath = sp_canvas_bpath_new(sp_desktop_sketch(_desktop), NULL);
            sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(_touchpath), 0xff0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
            sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(_touchpath), 0, SP_WIND_RULE_NONZERO);
        }
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(_touchpath), _touchpath_curve);

        sp_canvas_item_show(_touchpath);
        if (_rect)
            sp_canvas_item_hide(_rect);
    }
}
Exemplo n.º 10
0
static void sp_canvas_bpath_destroy(SPCanvasItem *object)
{
    SPCanvasBPath *cbp = SP_CANVAS_BPATH (object);

    if (cbp->curve) {
        cbp->curve = cbp->curve->unref();
    }

    if (SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy)
        (* SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy) (object);
}
Exemplo n.º 11
0
SPCanvasItem *
sp_canvas_bpath_new (SPCanvasGroup *parent, SPCurve *curve)
{
    g_return_val_if_fail (parent != NULL, NULL);
    g_return_val_if_fail (SP_IS_CANVAS_GROUP (parent), NULL);

    SPCanvasItem *item = sp_canvas_item_new (parent, SP_TYPE_CANVAS_BPATH, NULL);

    sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (item), curve);

    return item;
}
Exemplo n.º 12
0
static void
spdc_finish_endpoint (SPPencilContext *pc, NRPointF *p, gboolean snap, guint state)
{
	SPDrawContext *dc;

	dc = SP_DRAW_CONTEXT (pc);

	if (SP_CURVE_LENGTH (dc->red_curve) < 2) {
		/* Just a click, reset red curve and continue */
		g_print ("Finishing empty red curve\n");
		sp_curve_reset (dc->red_curve);
		sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);
	} else if (SP_CURVE_LENGTH (dc->red_curve) > 2) {
		g_warning ("Red curve length is %d", SP_CURVE_LENGTH (dc->red_curve));
		sp_curve_reset (dc->red_curve);
		sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);
	} else {
		ArtBpath *s, *e;
		/* We have actual line */
		if (snap) {
			/* Do (bogus?) snap */
			spdc_endpoint_snap (dc, p, state);
		}
		/* fixme: We really should test start and end anchors instead */
		s = SP_CURVE_SEGMENT (dc->red_curve, 0);
		e = SP_CURVE_SEGMENT (dc->red_curve, 1);
		if ((e->x3 == s->x3) && (e->y3 == s->y3)) {
			/* Empty line, reset red curve and continue */
			g_print ("Finishing zero length red curve\n");
			sp_curve_reset (dc->red_curve);
			sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);
		} else {
			/* Write curves to object */
			g_print ("Finishing real red curve\n");
			spdc_concat_colors_and_flush (dc, FALSE);
			dc->sa = NULL;
			dc->ea = NULL;
		}
	}
}
Exemplo n.º 13
0
static void
spdc_reset_colors (SPDrawContext *dc)
{
	/* Red */
	sp_curve_reset (dc->red_curve);
	sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);
	/* Blue */
	sp_curve_reset (dc->blue_curve);
	sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->blue_bpath), NULL);
	/* Green */
	while (dc->green_bpaths) {
		gtk_object_destroy (GTK_OBJECT (dc->green_bpaths->data));
		dc->green_bpaths = g_slist_remove (dc->green_bpaths, dc->green_bpaths->data);
	}
	sp_curve_reset (dc->green_curve);
	if (dc->green_anchor) {
		dc->green_anchor = sp_draw_anchor_destroy (dc->green_anchor);
	}
	dc->sa = NULL;
	dc->ea = NULL;
	dc->npoints = 0;
}
Exemplo n.º 14
0
static void
sp_draw_context_setup (SPEventContext *ec)
{
	SPDrawContext *dc;
	SPDesktop *dt;

	dc = SP_DRAW_CONTEXT (ec);
	dt = ec->desktop;

	if (((SPEventContextClass *) draw_parent_class)->setup)
		((SPEventContextClass *) draw_parent_class)->setup (ec);

	dc->selection = SP_DT_SELECTION (dt);

	/* Connect signals to track selection changes */
	g_signal_connect (G_OBJECT (dc->selection), "changed", G_CALLBACK (spdc_selection_changed), dc);
	g_signal_connect (G_OBJECT (dc->selection), "modified", G_CALLBACK (spdc_selection_modified), dc);

	/* Create red bpath */
	dc->red_bpath = sp_canvas_bpath_new (SP_DT_SKETCH (ec->desktop), NULL);
	sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (dc->red_bpath), dc->red_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
	/* Create red curve */
	dc->red_curve = sp_curve_new_sized (4);

	/* Create blue bpath */
	dc->blue_bpath = sp_canvas_bpath_new (SP_DT_SKETCH (ec->desktop), NULL);
	sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (dc->blue_bpath), dc->blue_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
	/* Create blue curve */
	dc->blue_curve = sp_curve_new_sized (8);

	/* Create green curve */
	dc->green_curve = sp_curve_new_sized (64);
	/* No green anchor by default */
	dc->green_anchor = NULL;

	spdc_set_attach (dc, FALSE);
}
Exemplo n.º 15
0
static void
fit_and_split (SPDrawContext * dc)
{
	NRPointF b[4];
	gdouble tolerance;

	g_assert (dc->npoints > 1);

	tolerance = SP_EVENT_CONTEXT (dc)->desktop->w2d[0] * TOLERANCE;
	tolerance = tolerance * tolerance;

	if (sp_bezier_fit_cubic (b, dc->p, dc->npoints, tolerance) > 0 && dc->npoints < SP_DRAW_POINTS_MAX) {
		/* Fit and draw and reset state */
		sp_curve_reset (dc->red_curve);
		sp_curve_moveto (dc->red_curve, b[0].x, b[0].y);
		sp_curve_curveto (dc->red_curve, b[1].x, b[1].y, b[2].x, b[2].y, b[3].x, b[3].y);
		sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve);
	} else {
		SPCurve *curve;
		SPCanvasItem *cshape;
		/* Fit and draw and copy last point */
		g_assert (!sp_curve_empty (dc->red_curve));
		sp_curve_append_continuous (dc->green_curve, dc->red_curve, 0.0625);
		curve = sp_curve_copy (dc->red_curve);

		/* fixme: */
		cshape = sp_canvas_bpath_new (SP_DT_SKETCH (SP_EVENT_CONTEXT (dc)->desktop), curve);
		sp_curve_unref (curve);
		sp_canvas_bpath_set_stroke (SP_CANVAS_BPATH (cshape), dc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);

		dc->green_bpaths = g_slist_prepend (dc->green_bpaths, cshape);

		dc->p[0] = dc->p[dc->npoints - 2];
		dc->p[1] = dc->p[dc->npoints - 1];
		dc->npoints = 2;
	}
}
Exemplo n.º 16
0
/**
 * Finalize addline.
 *
 * \todo
 * fixme: I'd like remove red reset from concat colors (lauris).
 * Still not sure, how it will make most sense.
 */
static void
spdc_finish_endpoint(SPPencilContext *const pc)
{
    if ( ( pc->red_curve->is_empty() )
         || ( *(pc->red_curve->first_point()) == *(pc->red_curve->second_point())   ) )
    {
        pc->red_curve->reset();
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL);
    } else {
        /* Write curves to object. */
        spdc_concat_colors_and_flush(pc, FALSE);
        pc->sa = NULL;
        pc->ea = NULL;
    }
}
Exemplo n.º 17
0
static void
spdc_set_endpoint (SPPencilContext *pc, NRPointF *p, guint state)
{
	SPDrawContext *dc;

	dc = SP_DRAW_CONTEXT (pc);

	g_assert (dc->npoints > 0);

	spdc_endpoint_snap (dc, p, state);

	dc->p[1] = *p;
	dc->npoints = 2;

	sp_curve_reset (dc->red_curve);
	sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y);
	sp_curve_lineto (dc->red_curve, dc->p[1].x, dc->p[1].y);
	sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve);
}
Exemplo n.º 18
0
static void
sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf)
{
    SPCanvasBPath *cbp = SP_CANVAS_BPATH (item);

    Geom::Rect area = buf->rect;

    if ( !cbp->curve  || 
         ((cbp->stroke_rgba & 0xff) == 0 && (cbp->fill_rgba & 0xff) == 0 ) || 
         cbp->curve->get_segment_count() < 1)
        return;

    if (!buf->ct)
        return;

    bool dofill = ((cbp->fill_rgba & 0xff) != 0);
    bool dostroke = ((cbp->stroke_rgba & 0xff) != 0);

    cairo_set_tolerance(buf->ct, 0.5);
    cairo_new_path(buf->ct);

    feed_pathvector_to_cairo (buf->ct, cbp->curve->get_pathvector(), cbp->affine, area,
        /* optimized_stroke = */ !dofill, 1);

    if (dofill) {
        // RGB / BGR
        ink_cairo_set_source_rgba32(buf->ct, cbp->fill_rgba);
        cairo_set_fill_rule(buf->ct, cbp->fill_rule == SP_WIND_RULE_EVENODD? CAIRO_FILL_RULE_EVEN_ODD
                            : CAIRO_FILL_RULE_WINDING);
        cairo_fill_preserve(buf->ct);
    }

    if (dostroke) {
        ink_cairo_set_source_rgba32(buf->ct, cbp->stroke_rgba);
        cairo_set_line_width(buf->ct, 1);
        if (cbp->dashes[0] != 0 && cbp->dashes[1] != 0) {
            cairo_set_dash (buf->ct, cbp->dashes, 2, 0);
        }
        cairo_stroke(buf->ct);
    } else {
        cairo_new_path(buf->ct);
    }
}
Exemplo n.º 19
0
static void
spdc_pen_set_ctrl (SPPenContext *pc, NRPointF *p, guint state)
{
	SPDrawContext *dc;

	dc = SP_DRAW_CONTEXT (pc);

	sp_canvas_item_show (pc->c1);
	sp_canvas_item_show (pc->cl1);

	if (dc->npoints == 2) {
		dc->p[1] = *p;
		sp_canvas_item_hide (pc->c0);
		sp_canvas_item_hide (pc->cl0);
		sp_ctrl_moveto (SP_CTRL (pc->c1), dc->p[1].x, dc->p[1].y);
		sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl1), dc->p[0].x, dc->p[0].y, dc->p[1].x, dc->p[1].y);
	} else if (dc->npoints == 5) {
		dc->p[4] = *p;
		sp_canvas_item_show (pc->c0);
		sp_canvas_item_show (pc->cl0);
		if (((pc->mode == SP_PEN_CONTEXT_MODE_CLICK) && (state & GDK_CONTROL_MASK)) ||
		    ((pc->mode == SP_PEN_CONTEXT_MODE_DRAG) && !(state & GDK_MOD1_MASK))) {
			gdouble dx, dy;
			dx = p->x - dc->p[3].x;
			dy = p->y - dc->p[3].y;
			dc->p[2].x = dc->p[3].x - dx;
			dc->p[2].y = dc->p[3].y - dy;
			sp_curve_reset (dc->red_curve);
			sp_curve_moveto (dc->red_curve, dc->p[0].x, dc->p[0].y);
			sp_curve_curveto (dc->red_curve, dc->p[1].x, dc->p[1].y, dc->p[2].x, dc->p[2].y, dc->p[3].x, dc->p[3].y);
			sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), dc->red_curve);
		}
		sp_ctrl_moveto (SP_CTRL (pc->c0), dc->p[2].x, dc->p[2].y);
		sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl0), dc->p[3].x, dc->p[3].y, dc->p[2].x, dc->p[2].y);
		sp_ctrl_moveto (SP_CTRL (pc->c1), dc->p[4].x, dc->p[4].y);
		sp_ctrlline_set_coords (SP_CTRLLINE (pc->cl1), dc->p[3].x, dc->p[3].y, dc->p[4].x, dc->p[4].y);
	} else {
		g_warning ("Something bad happened - npoints is %d", dc->npoints);
	}
}
Exemplo n.º 20
0
static double
sp_canvas_bpath_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item)
{
    SPCanvasBPath *cbp = SP_CANVAS_BPATH (item);

    if ( !cbp->curve  || 
         ((cbp->stroke_rgba & 0xff) == 0 && (cbp->fill_rgba & 0xff) == 0 ) || 
         cbp->curve->get_segment_count() < 1)
        return Geom::infinity();

    double width = 0.5;
    Geom::Rect viewbox = item->canvas->getViewbox();
    viewbox.expandBy (width);
    double dist = Geom::infinity();
    pathv_matrix_point_bbox_wind_distance(cbp->curve->get_pathvector(), cbp->affine, p, NULL, NULL, &dist, 0.5, &viewbox);

    if (dist <= 1.0) {
        *actual_item = item;
    }

    return dist;
}
Exemplo n.º 21
0
/* interpolates the sketched curve and tweaks the current sketch interpolation*/
static void
sketch_interpolate(SPPencilContext *pc)
{
    g_assert( pc->ps.size() > 1 );

    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
    double const tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) * 0.4;
    double const tolerance_sq = 0.02 * square( pc->desktop->w2d().descrim() * 
                                               tol) * exp(0.2*tol - 2);

    bool average_all_sketches = prefs->getBool("/tools/freehand/pencil/average_all_sketches", true);

    g_assert(is_zero(pc->req_tangent)
             || is_unit_vector(pc->req_tangent));
    Geom::Point const tHatEnd(0, 0);

    guint n_points  = pc->ps.size();
    pc->red_curve->reset();
    pc->red_curve_is_valid = false;

    Geom::Point * b = g_new(Geom::Point, 4*n_points);
    Geom::Point * points = g_new(Geom::Point, 4*n_points);
    for (unsigned i = 0; i < pc->ps.size(); i++) { 
        points[i] = pc->ps[i];
    }

    // worst case gives us a segment per point
    int max_segs = 4*n_points;

    int const n_segs = Geom::bezier_fit_cubic_r(b, points, n_points,
                                             tolerance_sq, max_segs);

    if ( n_segs > 0)
    {
        Geom::Path fit(b[0]);
        for (int c = 0; c < n_segs; c++) { 
            fit.appendNew<Geom::CubicBezier>(b[4*c+1], b[4*c+2], b[4*c+3]);
        }
        Geom::Piecewise<Geom::D2<Geom::SBasis> > fit_pwd2 = fit.toPwSb();

        double t =0.;
        if ( pc->sketch_n > 0 ) {
            if (average_all_sketches) {
                // Average = (sum of all) / n
                //         = (sum of all + new one) / n+1
                //         = ((old average)*n + new one) / n+1
                t = pc->sketch_n / (pc->sketch_n + 1.);
            } else {
                t = 0.5;
            }
            pc->sketch_interpolation = Geom::lerp(t, fit_pwd2, pc->sketch_interpolation);
        } else {
            pc->sketch_interpolation = fit_pwd2;
        }
        pc->sketch_n++;

        pc->green_curve->reset();
        pc->green_curve->set_pathvector(Geom::path_from_piecewise(pc->sketch_interpolation, 0.01));
        sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->green_curve);

        /* Fit and draw and copy last point */
        g_assert(!pc->green_curve->is_empty());

        /* Set up direction of next curve. */
        {
            Geom::CubicBezier const * last_seg = dynamic_cast<Geom::CubicBezier const *>(pc->green_curve->last_segment());
            g_assert( last_seg );      // Relevance: validity of (*last_seg)[2]
            pc->p[0] = last_seg->finalPoint();
            pc->npoints = 1;
            Geom::Point const req_vec( pc->p[0] - (*last_seg)[2] );
            pc->req_tangent = ( ( Geom::is_zero(req_vec) || !in_svg_plane(req_vec) )
                                ? Geom::Point(0, 0)
                                : Geom::unit_vector(req_vec) );
        }
    }
    g_free(b);
    g_free(points);
    pc->ps.clear();
}
Exemplo n.º 22
0
static void
spdc_concat_colors_and_flush (SPDrawContext *dc, gboolean forceclosed)
{
	SPCurve *c;

	/* Concat RBG */
	c = dc->green_curve;

	/* Green */
	dc->green_curve = sp_curve_new_sized (64);
	while (dc->green_bpaths) {
		gtk_object_destroy (GTK_OBJECT (dc->green_bpaths->data));
		dc->green_bpaths = g_slist_remove (dc->green_bpaths, dc->green_bpaths->data);
	}
	/* Blue */
	sp_curve_append_continuous (c, dc->blue_curve, 0.0625);
	sp_curve_reset (dc->blue_curve);
	sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->blue_bpath), NULL);
	/* Red */
	sp_curve_append_continuous (c, dc->red_curve, 0.0625);
	sp_curve_reset (dc->red_curve);
	sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (dc->red_bpath), NULL);

	/* Step A - test, whether we ended on green anchor */
	if (forceclosed || (dc->green_anchor && dc->green_anchor->active)) {
		g_print ("We hit green anchor, closing Green-Blue-Red\n");
		sp_curve_closepath_current (c);
		/* Closed path, just flush */
		spdc_flush_white (dc, c);
		sp_curve_unref (c);
		return;
	}

	/* Step B - both start and end anchored to same curve */
	if (dc->sa && dc->ea && (dc->sa->curve == dc->ea->curve)) {
		g_print ("We hit bot start and end of single curve, closing paths\n");
		if (dc->sa->start) {
			SPCurve *r;
			g_print ("Reversing curve\n");
			r = sp_curve_reverse (c);
			sp_curve_unref (c);
			c = r;
		}
		sp_curve_append_continuous (dc->sa->curve, c, 0.0625);
		sp_curve_unref (c);
		sp_curve_closepath_current (dc->sa->curve);
		spdc_flush_white (dc, NULL);
		return;
	}

	/* Step C - test start */
	if (dc->sa) {
		SPCurve *s;
		g_print ("Curve start hit anchor\n");
		s = dc->sa->curve;
		dc->white_curves = g_slist_remove (dc->white_curves, s);
		if (dc->sa->start) {
			SPCurve *r;
			g_print ("Reversing curve\n");
			r = sp_curve_reverse (s);
			sp_curve_unref (s);
			s = r;
		}
		sp_curve_append_continuous (s, c, 0.0625);
		sp_curve_unref (c);
		c = s;
	}

	/* Step D - test end */
	if (dc->ea) {
		SPCurve *e;
		g_print ("Curve end hit anchor\n");
		e = dc->ea->curve;
		dc->white_curves = g_slist_remove (dc->white_curves, e);
		if (!dc->ea->start) {
			SPCurve *r;
			g_print ("Reversing curve\n");
			r = sp_curve_reverse (e);
			sp_curve_unref (e);
			e = r;
		}
		sp_curve_append_continuous (c, e, 0.0625);
		sp_curve_unref (e);
	}

	spdc_flush_white (dc, c);

	sp_curve_unref (c);
}