Example #1
0
static int
sp_spiral_snappoints (SPItem *item, NRPointF *p, int size)
{
#if 0
	/* fixme: (Lauris) */
	SPSpiral *spiral;
	ArtPoint * p, p1, p2, p3;
	gdouble affine[6];
	
	spiral = SP_SPIRAL(item);
	
	sp_spiral_get_xy (spiral, 0.0, &p1);
	sp_spiral_get_xy (spiral, spiral->t0, &p2);
	sp_spiral_get_xy (spiral, 1.0, &p3);
	
	sp_item_i2d_affine (item, affine);
	
	p = g_new (ArtPoint,1);
	art_affine_point (p, &p1, affine);
	points = g_slist_append (points, p);
	
	p = g_new (ArtPoint,1);
	art_affine_point (p, &p2, affine);
	points = g_slist_append (points, p);
	
	p = g_new (ArtPoint,1);
	art_affine_point (p, &p3, affine);
	points = g_slist_append (points, p);
#else
	if (((SPItemClass *) parent_class)->snappoints)
		return ((SPItemClass *) parent_class)->snappoints (item, p, size);
#endif
	
	return 0;
}
Example #2
0
static void
textbox_flip (ItemData *data, gboolean horizontal, SheetPos *center)
{
	double affine[6];
	ArtPoint src, dst;
	Textbox *textbox;
	TextboxPriv *priv;
	SheetPos b1, b2;
	SheetPos textbox_center, delta;

	g_return_if_fail (data != NULL);
	g_return_if_fail (IS_TEXTBOX (data));

	textbox = TEXTBOX (data);

	if (center) {
		item_data_get_absolute_bbox (ITEM_DATA (textbox), &b1, &b2);
		textbox_center.x = b1.x + (b2.x - b1.x) / 2;
		textbox_center.y = b1.y + (b2.y - b1.y) / 2;
	}

	priv = textbox->priv;

	if (horizontal)
		art_affine_scale (affine, -1, 1);
	else
		art_affine_scale (affine, 1, -1);

	/*
	 * Let the views (canvas items) know about the rotation.
	 */
	g_signal_emit_by_name(G_OBJECT (textbox), "flipped", horizontal);

	if (center) {
		SheetPos textbox_pos;

		item_data_get_pos (ITEM_DATA (textbox), &textbox_pos);

		src.x = textbox_center.x - center->x;
		src.y = textbox_center.y - center->y;
		art_affine_point (&dst, &src, affine);

		delta.x = -src.x + dst.x;
		delta.y = -src.y + dst.y;

		item_data_move (ITEM_DATA (textbox), &delta);
	}
}
Example #3
0
/**
 * art_rgb_affine: Affine transform source RGB image and composite.
 * @dst: Destination image RGB buffer.
 * @x0: Left coordinate of destination rectangle.
 * @y0: Top coordinate of destination rectangle.
 * @x1: Right coordinate of destination rectangle.
 * @y1: Bottom coordinate of destination rectangle.
 * @dst_rowstride: Rowstride of @dst buffer.
 * @src: Source image RGB buffer.
 * @src_width: Width of source image.
 * @src_height: Height of source image.
 * @src_rowstride: Rowstride of @src buffer.
 * @affine: Affine transform.
 * @level: Filter level.
 * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
 *
 * Affine transform the source image stored in @src, compositing over
 * the area of destination image @dst specified by the rectangle
 * (@x0, @y0) - (@x1, @y1). As usual in libart, the left and top edges
 * of this rectangle are included, and the right and bottom edges are
 * excluded.
 *
 * The @alphagamma parameter specifies that the alpha compositing be done
 * in a gamma-corrected color space. Since the source image is opaque RGB,
 * this argument only affects the edges. In the current implementation,
 * it is ignored.
 *
 * The @level parameter specifies the speed/quality tradeoff of the
 * image interpolation. Currently, only ART_FILTER_NEAREST is
 * implemented.
 **/
void
art_rgb_affine (art_u8 *dst, int x0, int y0, int x1, int y1, int dst_rowstride,
		const art_u8 *src,
		int src_width, int src_height, int src_rowstride,
		const double affine[6],
		ArtFilterLevel level,
		ArtAlphaGamma *alphagamma)
{
  /* Note: this is a slow implementation, and is missing all filter
     levels other than NEAREST. It is here for clarity of presentation
     and to establish the interface. */
  int x, y;
  double inv[6];
  art_u8 *dst_p, *dst_linestart;
  const art_u8 *src_p;
  ArtPoint pt, src_pt;
  int src_x, src_y;
  int run_x0, run_x1;

  dst_linestart = dst;
  art_affine_invert (inv, affine);
  for (y = y0; y < y1; y++)
    {
      pt.y = y + 0.5;
      run_x0 = x0;
      run_x1 = x1;
      art_rgb_affine_run (&run_x0, &run_x1, y, src_width, src_height,
			  inv);
      dst_p = dst_linestart + (run_x0 - x0) * 3;
      for (x = run_x0; x < run_x1; x++)
	{
	  pt.x = x + 0.5;
	  art_affine_point (&src_pt, &pt, inv);
	  src_x = floor (src_pt.x);
	  src_y = floor (src_pt.y);
	  src_p = src + (src_y * src_rowstride) + src_x * 3;
	  dst_p[0] = src_p[0];
	  dst_p[1] = src_p[1];
	  dst_p[2] = src_p[2];
	  dst_p += 3;
	}
      dst_linestart += dst_rowstride;
    }
}
Example #4
0
static double
gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
				GnomeCanvasItem **actual_item)
{
#ifdef HACKISH_AFFINE
	double i2w[6], w2c[6], i2c[6], c2i[6];
	ArtPoint c, i;
#endif

#ifdef HACKISH_AFFINE
	gnome_canvas_item_i2w_affine (item, i2w);
	gnome_canvas_w2c_affine (item->canvas, w2c);
	art_affine_multiply (i2c, i2w, w2c);
	art_affine_invert (c2i, i2c);
	c.x = cx;
	c.y = cy;
	art_affine_point (&i, &c, c2i);
	x = i.x;
	y = i.y;
#endif

	return (* GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT_GET_CLASS (item))->point) (
		item, x, y, cx, cy, actual_item);
}
Example #5
0
static void
test_affine (void) {
    double src[6];
    double dst[6];
    double src2[6];
    char str[128];
    int i;
    ArtPoint ps, pd, ptmp;

    for (i = 0; i < 6; i++)
    {
        src[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
        src2[i] = (rand () * 2.0 / RAND_MAX) - 1.0;
    }
#if 0
    src[0] = 0.9999999;
    src[1] = -0.000001;
    src[2] = 0.000001;
    src[3] = 0.9999999;
    src[4] = 0;
    src[5] = 0;
#if 1
    src[0] = 0.98480775;
    src[1] = -0.17364818;
    src[2] = 0.17364818;
    src[3] = 0.98480775;
#endif

    src2[0] = 0.98480775;
    src2[1] = -0.17364818;
    src2[2] = 0.17364818;
    src2[3] = 0.98480775;
#endif


    ps.x = rand() * 100.0 / RAND_MAX;
    ps.y = rand() * 100.0 / RAND_MAX;

    art_affine_point (&pd, &ps, src);
    art_affine_invert (dst, src);
    art_affine_point (&ptmp, &pd, dst);
    art_affine_to_string (str, src);
    printf ("src = %s\n", str);
    art_affine_to_string (str, dst);
    printf ("dst = %s\n", str);
    printf ("point (%g, %g) -> (%g, %g) -> (%g, %g)\n",
            ps.x, ps.y, pd.x, pd.y, ptmp.x, ptmp.y);

    art_affine_point (&ptmp, &ps, src);
    art_affine_point (&pd, &ptmp, src2);
    art_affine_to_string (str, src2);
    printf ("src2 = %s\n", str);
    printf ("point (%g, %g) -> (%g, %g) -> (%g, %g)\n",
            ps.x, ps.y, ptmp.x, ptmp.y, pd.x, pd.y);
    art_affine_multiply (dst, src, src2);
    art_affine_to_string (str, dst);
    printf ("dst = %s\n", str);
    art_affine_point (&pd, &ps, dst);
    printf ("point (%g, %g) -> (%g, %g)\n",
            ps.x, ps.y, pd.x, pd.y);

}
Example #6
0
GnomePosGlyphList *
gnome_pgl_from_gl (const GnomeGlyphList * gl, const gdouble * transform, guint flags)
{
	static gdouble identity[] = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
	GnomePosGlyphList * pgl;
	gboolean fontfound;
	gint allocated_strings;
	gint r;
	gint cg, cr;
	ArtPoint pos, pen;
	gboolean usemetrics;
	gint lastglyph;
	gboolean advance;
	ArtPoint letterspace;
	gdouble kerning;
	GnomeFont * font;
	guint32 color;
	gboolean needstring;
	gint currentstring;
	gint sptr;
	ArtPoint p;

	g_return_val_if_fail (gl != NULL, NULL);
	g_return_val_if_fail (GNOME_IS_GLYPHLIST (gl), NULL);
	if (!transform)
		transform = identity;

	/* Special case */
	if (gl->g_length < 1) {
		pgl = g_new (GnomePosGlyphList, 1);
		pgl->glyphs = NULL;
		pgl->strings = NULL;
		pgl->num_strings = 0;
		return pgl;
	}
	/* We need font rule */
	g_return_val_if_fail (gl->r_length > 0, NULL);
	g_return_val_if_fail (gl->rules[0].code == GGL_POSITION, NULL);
	g_return_val_if_fail (gl->rules[0].value.ival == 0, NULL);
	fontfound = FALSE;
	for (r = 1; (r < gl->r_length) && (gl->rules[r].code != GGL_POSITION); r++) {
		if (gl->rules[r].code == GGL_FONT) {
			g_return_val_if_fail (gl->rules[r].value.font != NULL, NULL);
			g_return_val_if_fail (GNOME_IS_FONT (gl->rules[r].value.font), NULL);
			fontfound = TRUE;
			break;
		}
	}
	g_return_val_if_fail (fontfound, NULL);

	/* Initialize pgl */
	pgl = g_new (GnomePosGlyphList, 1);
	pgl->glyphs = g_new (GnomePosGlyph, gl->g_length);
	pgl->strings = g_new (GnomePosString, 1);
	pgl->num_strings = 0;
	allocated_strings = 1;

	/* State machine */
	sptr = 0;
	pen.x = transform[4];
	pen.y = transform[5];
	usemetrics = FALSE;
	lastglyph = -1;
	advance = TRUE;
	letterspace.x = 0.0;
	letterspace.y = 0.0;
	kerning = 0.0;
	font = NULL;
	color = 0x000000ff;
	needstring = TRUE;
	currentstring = -1;
	cr = 0;
	for (cg = 0; cg < gl->g_length; cg++) {
		/* Collect rules */
		while ((cr < gl->r_length) && ((gl->rules[cr].code != GGL_POSITION) || (gl->rules[cr].value.ival <= cg))) {
			switch (gl->rules[cr].code) {
			case GGL_MOVETOX:
				/* moveto is special case */
				g_return_val_if_fail (cr + 1 < gl->r_length, NULL);
				g_return_val_if_fail (gl->rules[cr + 1].code == GGL_MOVETOY, NULL);
				pos.x = gl->rules[cr].value.dval;
				pos.y = gl->rules[cr + 1].value.dval;
				cr += 1;
				usemetrics = FALSE;
				art_affine_point (&pen, &pos, transform);
				break;
			case GGL_RMOVETOX:
				/* rmoveto is special case */
				g_return_val_if_fail (cr + 1 < gl->r_length, NULL);
				g_return_val_if_fail (gl->rules[cr + 1].code == GGL_RMOVETOY, NULL);
				pos.x = gl->rules[cr].value.dval;
				pos.y = gl->rules[cr + 1].value.dval;
				cr += 1;
				usemetrics = FALSE;
				pen.x += pos.x * transform[0] + pos.y * transform[2];
				pen.y += pos.x * transform[1] + pos.y * transform[3];
				break;
			case GGL_ADVANCE:
				advance = gl->rules[cr].value.bval;
				break;
			case GGL_LETTERSPACE:
				p.x = gl->rules[cr].value.dval;
				p.y = 0.0;
				letterspace.x = p.x * transform[0] + p.y * transform[2];
				letterspace.y = p.x * transform[1] + p.y * transform[3];
				break;
			case GGL_KERNING:
				kerning = gl->rules[cr].value.dval;
				break;
			case GGL_FONT:
				font = gl->rules[cr].value.font;
				g_return_val_if_fail (font != NULL, NULL);
				g_return_val_if_fail (GNOME_IS_FONT (font), NULL);
				needstring = TRUE;
				break;
			case GGL_COLOR:
				color = gl->rules[cr].value.color;
				needstring = TRUE;
				break;
			}
			cr += 1;
		}

		if (needstring) {
			/* Add new string instance */
			g_assert (GNOME_IS_FONT (font));
			if (pgl->num_strings >= allocated_strings) {
				allocated_strings += 4;
				pgl->strings = g_renew (GnomePosString, pgl->strings, allocated_strings);
			}
			currentstring = pgl->num_strings;
			pgl->num_strings += 1;
			pgl->strings[currentstring].start = cg;
			pgl->strings[currentstring].length = 0;
			pgl->strings[currentstring].rfont = gnome_font_get_rfont (font, transform);
			pgl->strings[currentstring].color = color;
			needstring = FALSE;
		}
		/* Rules are parsed and currentstring points to active string */
		/* Process glyph */
		pgl->glyphs[cg].glyph = gl->glyphs[cg];
		pgl->strings[currentstring].length += 1;
		if (usemetrics && (lastglyph > 0) && (pgl->glyphs[cg].glyph > 0)) {
			/* Need to add kerning */
			if (gnome_rfont_get_glyph_stdkerning (pgl->strings[currentstring].rfont, lastglyph, pgl->glyphs[cg].glyph, &p)) {
				pen.x += p.x;
				pen.y += p.y;
			}
			pen.x += letterspace.x;
			pen.y += letterspace.y;
		}
		pgl->glyphs[cg].x = pen.x;
		pgl->glyphs[cg].y = pen.y;
		if (advance) {
			if (gnome_rfont_get_glyph_stdadvance (pgl->strings[currentstring].rfont, pgl->glyphs[cg].glyph, &p)) {
				pen.x += p.x;
				pen.y += p.y;
			}
		}
		usemetrics = TRUE;
		lastglyph = pgl->glyphs[cg].glyph;
	}

	return pgl;
}
Example #7
0
static void
relation_arrow_draw (GnomeCanvasItem *item,
		     GdkDrawable     *drawable,
		     gint             x,
		     gint             y,
		     gint             width,
		     gint             height)
{
	PlannerRelationArrow     *arrow;
	PlannerRelationArrowPriv *priv;
#ifdef USE_AFFINE
	gdouble                   i2c[6];
	ArtPoint                  i1, i2, c1, c2;
#else
	gdouble                   i2w_dx;
	gdouble                   i2w_dy;
	gdouble                   dx1, dy1, dx2, dy2;
#endif
	gint                      cx1, cy1, cx2, cy2;
	GdkGC                    *gc;
	GdkPoint                  points[4];
	gint                      i;

	arrow = PLANNER_RELATION_ARROW (item);
	priv = arrow->priv;

	gc = gdk_gc_new (drawable);
	gdk_gc_set_line_attributes (gc,
				    1,
				    GDK_LINE_SOLID,
				    GDK_CAP_BUTT,
				    GDK_JOIN_MITER);

	/* Silence warning. */
	cx1 = 0;
	cy1 = 0;
	cx2 = 0;
	cy2 = 0;

#ifdef USE_AFFINE
	/* Get item area in canvas coordinates. */
	gnome_canvas_item_i2c_affine (item, i2c);
#endif

	for (i = 0; i < priv->num_points - 1; i++) {
#ifdef USE_AFFINE
		i1.x = priv->points[i].x;
		i1.y = priv->points[i].y;
		i2.x = priv->points[i+1].x;
		i2.y = priv->points[i+1].y;
		art_affine_point (&c1, &i1, i2c);
		art_affine_point (&c2, &i2, i2c);
		cx1 = floor (c1.x + 0.5) - x;
		cy1 = floor (c1.y + 0.5) - y;
		cx2 = floor (c2.x + 0.5) - x;
		cy2 = floor (c2.y + 0.5) - y;
#else
		i2w_dx = 0.0;
		i2w_dy = 0.0;
		gnome_canvas_item_i2w (item, &i2w_dx, &i2w_dy);

		dx1 = priv->points[i].x;
		dy1 = priv->points[i].y;
		dx2 = priv->points[i+1].x;
		dy2 = priv->points[i+1].y;

		gnome_canvas_w2c (item->canvas,
				  dx1 + i2w_dx,
				  dy1 + i2w_dy,
				  &cx1,
				  &cy1);

		gnome_canvas_w2c (item->canvas,
				  dx2 + i2w_dx,
				  dy2 + i2w_dy,
				  &cx2,
				  &cy2);

		cx1 -= x;
		cy1 -= y;
		cx2 -= x;
		cy2 -= y;
#endif

		gdk_draw_line (drawable,
			       gc,
			       cx1,
			       cy1,
			       cx2,
			       cy2);
	}

	relation_arrow_setup_arrow (priv->arrow_dir,
					points,
					cx1,
					cy1,
					cx2,
					cy2);

	gdk_draw_polygon (drawable,
			  gc,
			  TRUE,
			  (GdkPoint *) &points,
			  4);

	g_object_unref (gc);
}