コード例 #1
0
ファイル: textbox.c プロジェクト: Miuler/oregano
/* static */
void
textbox_update_bbox (Textbox *textbox)
{
	PangoFontDescription *font;
	/*
	Unused variables
	int width;
	int rbearing;
	int lbearing;
	int ascent, descent;
	*/
	SheetPos b1, b2;
	TextboxPriv *priv;

	priv = textbox->priv;

	font = pango_font_description_from_string(priv->font);
	/* TODO : Find out how to do this with Pango. */
	/* gdk_string_extents (font,
		priv->text,
		&lbearing,
		&rbearing,
		&width,
		&ascent,
		&descent);
		gdk_font_unref (font);
	*/
	b1.x = 0.0;
	b1.y = 0.0-5; // - font->ascent;
	b2.x = 0.0+5; // + rbearing;
	b2.y = 0.0+5; // + font->descent;

	item_data_set_relative_bbox (ITEM_DATA (textbox), &b1, &b2);
	pango_font_description_free(font);
}
コード例 #2
0
ファイル: wire.c プロジェクト: neuroidss/oregano
void wire_update_bbox (Wire *wire)
{
    Coords b1, b2, pos, length;

    wire_get_pos_and_length (wire, &pos, &length);

    b1.x = b1.y = 0.0;
    b2 = length;

    item_data_set_relative_bbox (ITEM_DATA (wire), &b1, &b2);
}
コード例 #3
0
ファイル: part.c プロジェクト: rodolforg/oregano
static void
part_update_bbox (Part *part)
{
	GSList *objects;
	LibrarySymbol *symbol;
	SymbolObject *object;
	GooCanvasPoints *points;
	int i;

	Coords b1, b2;

	symbol = library_get_symbol (part->priv->symbol_name);
	if (symbol == NULL) {
		g_warning ("Couldn't find the requested symbol.");
		return;
	}

	b1.x = b1.y = b2.x = b2.y = 0.0;

	for (objects = symbol->symbol_objects; objects;
	     objects = objects->next) {
		object = objects->data;
		switch (object->type) {
		case SYMBOL_OBJECT_LINE:
			points = object->u.uline.line;

			for (i = 0; i < points->num_points; i++) {
				b1.x = MIN (points->coords[i * 2], b1.x);
				b1.y = MIN (points->coords[i * 2 + 1], b1.y);

				b2.x = MAX (points->coords[i * 2], b2.x);
				b2.y = MAX (points->coords[i * 2 + 1], b2.y);
			}
			break;

		case SYMBOL_OBJECT_ARC:
			b1.x = MIN (object->u.arc.x1, b1.x);
			b1.y = MIN (object->u.arc.y1, b1.y);

			b2.x = MAX (object->u.arc.x1, b2.x);
			b2.y = MAX (object->u.arc.y1, b2.y);

			b1.x = MIN (object->u.arc.x2, b1.x);
			b1.y = MIN (object->u.arc.y2, b1.y);

			b2.x = MAX (object->u.arc.x2, b2.x);
			b2.y = MAX (object->u.arc.y2, b2.y);

			break;

		case SYMBOL_OBJECT_TEXT:
			{
				//FIXME
				/*GdkFont *font = gdk_font_load ("Sans 10");
				 b1.x = b1.y =  0;
				 b2.x = 2*object->u.text.x +
				 gdk_string_width (font, object->u.text.str );
				 b2.y = 2*object->u.text.y +
				 gdk_string_height (font,object->u.text.str );
				*/
			}
			break;


		default:
			g_warning ("Unknown symbol object.\n");
			continue;
		}
	}

	item_data_set_relative_bbox (ITEM_DATA (part), &b1, &b2);
}
コード例 #4
0
ファイル: part.c プロジェクト: rodolforg/oregano
/**
 * flip a part in a given direction
 * @direction gives the direction the item will be flipped, end users pov!
 * @center the center to flip over - currently ignored FIXME
 */
static void
part_flip (ItemData *data, IDFlip direction, Coords *center)
{
	Part *part;
	PartPriv *priv;
	int i;
	cairo_matrix_t affine;
	double x, y;
	double scale_v, scale_h;
	gboolean handler_connected;
	Coords pos, trans;
	Coords b1, b2;
	Coords pos_new, pos_old, delta;
	//FIXME properly recenter after flipping
	//Coords part_center_before, part_center_after, delta;

	g_return_if_fail (data);
	g_return_if_fail (IS_PART (data));

	part = PART (data);
	priv = part->priv;

	item_data_get_pos (data, &trans);

	// mask, just for the sake of cleanness
	direction &= ID_FLIP_MASK;
	
	// TODO evaluate if we really want to be able to do double flips (180* rots via flipping)
	g_assert (direction != ID_FLIP_MASK);


	// create a transformation _relativ_ to the current _state_
	// reverse axis and fix the created offset by adding 2*pos.x or .y
	
	// convert the flip direction to binary, used in the matrix setup
	// keep in mind that we do relativ manipulations within the model
	// which in turn makes this valid for all rotations!
	scale_h = ((direction & ID_FLIP_HORIZ) != 0) ? -1. : 1.;
	scale_v = ((direction & ID_FLIP_VERT) != 0) ? -1. : 1.;

	// magic, if we are in either 270 or 90 state, we need to rotate the flip state by 90° to draw it properly
	// TODO maybe better put this into the rotation function
	if ((priv->rotation / 90) % 2 == 1) {
		priv->flip ^= ID_FLIP_MASK;
	}
	// toggle the direction
	priv->flip ^= direction;
	if ((priv->flip & ID_FLIP_MASK)== ID_FLIP_MASK) {
		priv->flip = ID_FLIP_NONE;
		priv->rotation += 180;
		priv->rotation %= 360;
	}

	cairo_matrix_init_scale (&affine, scale_h, scale_v);

	item_data_get_pos (data, &pos_old);
	pos_new = pos_old;
	cairo_matrix_transform_point (&affine, &pos_new.x, &pos_new.y);

	g_printf ("\ncenter %p [old] x=%lf,y=%lf -->", data, pos_old.x, pos_old.y);
	g_printf ("  x=%lf, y=%lf\n", pos_new.x, pos_new.y);
	delta.x = - pos_new.x + pos_old.x;
	delta.y = - pos_new.y + pos_old.y;

	// flip the pins
	for (i = 0; i < priv->num_pins; i++) {

		x = priv->pins[i].offset.x;
		y = priv->pins[i].offset.y;
		cairo_matrix_transform_point (&affine, &x, &y);

		if (fabs (x) < 1e-2)
			x = 0.0;
		if (fabs (y) < 1e-2)
			y = 0.0;

		priv->pins[i].offset.x = x;
		priv->pins[i].offset.y = y;
	}
	item_data_snap (data);

	// tell the view
	handler_connected = g_signal_handler_is_connected (G_OBJECT (part), 
	                                                   ITEM_DATA(part)->flipped_handler_id);
	if (handler_connected) {
		g_signal_emit_by_name (G_OBJECT (part), "flipped", priv->flip);

		// TODO - proper boundingbox center calculation

		item_data_get_relative_bbox (ITEM_DATA (part), &b1, &b2);

		// flip the bounding box.
		cairo_matrix_transform_point (&affine, &b1.x, &b1.y);
		cairo_matrix_transform_point (&affine, &b2.x, &b2.y);

		item_data_set_relative_bbox (ITEM_DATA (part), &b1, &b2);
		item_data_set_pos (ITEM_DATA (part), &pos);

		// FIXME - proper recenter to boundingbox center
	}
	if (g_signal_handler_is_connected (G_OBJECT (part),
	                                   ITEM_DATA (part)->changed_handler_id)) {
		g_signal_emit_by_name (G_OBJECT (part),
		                       "changed");
	}

}
コード例 #5
0
ファイル: part.c プロジェクト: rodolforg/oregano
/**
 * rotate an item by an @angle increment (may be negative)
 * @angle the increment the item will be rotated (usually 90° steps)
 * @center_pos if rotated as part of a group, this is the center to rotate around
 * FIXME XXX TODO an issue arises as the center changes with part_rotate
 * FIXME XXX TODO the view callback needs to compensate this somehow
 */
static void
part_rotate (ItemData *data, int angle, Coords *center_pos)
{
	cairo_matrix_t affine;
	double x, y;
	Part *part;
	PartPriv *priv;
	int i, tot_rotation;
	Coords b1, b2;
	Coords part_center_before, part_center_after, delta;
	Coords delta_cp_before, delta_cp_after;
	gboolean handler_connected;

	g_return_if_fail (data);
	g_return_if_fail (IS_PART (data));

	if (angle == 0)
		return;

	part = PART (data);

	priv = part->priv;

	tot_rotation = (priv->rotation + angle + 360) % 360;

	NG_DEBUG ("rotation: angle=%i tot_rotation=%i", angle, tot_rotation);

	// use the cairo matrix funcs to transform the pin
	// positions relative to the item center
	// this is only indirectly related to displaying
	cairo_matrix_init_rotate (&affine, (double)angle * M_PI / 180.);

	if (center_pos) {
		delta_cp_before = coords_sub (&part_center_before, center_pos);
		delta_cp_after = delta_cp_before;
		cairo_matrix_transform_point (&affine, &delta_cp_after.x, &delta_cp_after.y);
	}

	priv->rotation = tot_rotation;
	angle = tot_rotation;

	// Rotate the pins.
	for (i = 0; i < priv->num_pins; i++) {
		x = priv->pins[i].offset.x;
		y = priv->pins[i].offset.y;
		cairo_matrix_transform_point (&affine, &x, &y);

		if (fabs (x) < 1e-2)
			x = 0.0;
		if (fabs (y) < 1e-2)
			y = 0.0;

		priv->pins[i].offset.x = x;
		priv->pins[i].offset.y = y;
	}

	// Rotate the bounding box, recenter to old center
	item_data_get_relative_bbox (ITEM_DATA (part), &b1, &b2);
	part_center_before = coords_average (&b1, &b2);

	cairo_matrix_transform_point (&affine, &b1.x, &b1.y);
	cairo_matrix_transform_point (&affine, &b2.x, &b2.y);

	item_data_set_relative_bbox (ITEM_DATA (part), &b1, &b2);
	part_center_after = coords_average (&b1, &b2);

	delta = coords_sub (&part_center_before, &part_center_after);
	if (center_pos) {
		Coords diff = coords_sub (&delta_cp_after, &delta_cp_before);
		coords_add (&delta, &diff);
	}
	item_data_move (data, &delta);
	item_data_snap (data);

	handler_connected = g_signal_handler_is_connected (G_OBJECT (part),
	                                   ITEM_DATA (part)->rotated_handler_id);
	if (handler_connected) {
		g_signal_emit_by_name (G_OBJECT (part),
		                       "rotated", tot_rotation);
	}

	handler_connected = g_signal_handler_is_connected (G_OBJECT (part),
	                                   ITEM_DATA (part)->changed_handler_id);
	if (handler_connected) {
		g_signal_emit_by_name (G_OBJECT (part),
		                       "changed");
	}
}