/*! \brief Modify the description of a circle OBJECT. * \par Function Description * This function modifies the description of the circle object <B>*object</B> * depending on <B>whichone</B> that give the meaning of the <B>x</B> and <B>y</B> * parameters. * * If <B>whichone</B> is equal to <B>CIRCLE_CENTER</B>, the new center of the * circle is given by (<B>x</B>,<B>y</B>) where <B>x</B> and <B>y</B> are in world units. * * If <B>whichone</B> is equal to <B>CIRCLE_RADIUS</B>, the radius is given by * <B>x</B> - in world units. <B>y</B> is ignored. * * The bounding box of the circle object is updated after the modification of its * parameters. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object Circle OBJECT to modify. * \param [in] x New center x coordinate, or radius value. * \param [in] y New center y coordinate. * Unused if radius is being modified. * \param [in] whichone Which circle parameter to modify. * * <B>whichone</B> can have the following values: * <DL> * <DT>*</DT><DD>CIRCLE_CENTER * <DT>*</DT><DD>CIRCLE_RADIUS * </DL> */ void o_circle_modify(TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { o_emit_pre_change_notify (toplevel, object); switch(whichone) { case CIRCLE_CENTER: /* modify the center of the circle */ object->circle->center_x = x; object->circle->center_y = y; break; case CIRCLE_RADIUS: /* modify the radius of the circle */ if (x == 0) { s_log_message(_("Null radius circles are not allowed\n")); return; } object->circle->radius = x; break; default: break; } /* recalculate the boundings */ o_circle_recalc(toplevel, object); o_emit_change_notify (toplevel, object); }
/*! \brief Modify the description of a line OBJECT. * \par Function Description * This function modifies the coordinates of one of the two ends of * the line described by <B>*object</B>. The new coordinates of this end, * identified by <B>whichone</B>, are given by <B>x</B> and <B>y</B> * in world unit. * * The coordinates of the end of line is modified in the world * coordinate system. Screen coordinates and boundings are then updated. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object Line OBJECT to modify. * \param [in] x New x coordinate. * \param [in] y New y coordinate. * \param [in] whichone Which line parameter to modify. * * <B>whichone</B> can have the following values: * <DL> * <DT>*</DT><DD>LINE_END1 * <DT>*</DT><DD>LINE_END2 * </DL> */ void o_line_modify(TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { o_emit_pre_change_notify (toplevel, object); /* change one of the end of the line */ switch (whichone) { case LINE_END1: object->line->x[0] = x; object->line->y[0] = y; break; case LINE_END2: object->line->x[1] = x; object->line->y[1] = y; break; default: return; } /* recalculate the bounding box */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief Modify the description of a circle OBJECT. * \par Function Description * This function modifies the description of the circle object <B>*object</B> * depending on <B>whichone</B> that give the meaning of the <B>x</B> and <B>y</B> * parameters. * * If <B>whichone</B> is equal to <B>CIRCLE_CENTER</B>, the new center of the * circle is given by (<B>x</B>,<B>y</B>) where <B>x</B> and <B>y</B> are in world units. * * If <B>whichone</B> is equal to <B>CIRCLE_RADIUS</B>, the radius is given by * <B>x</B> - in world units. <B>y</B> is ignored. * * The bounding box of the circle object is updated after the modification of its * parameters. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object Circle OBJECT to modify. * \param [in] x New center x coordinate, or radius value. * \param [in] y New center y coordinate. * Unused if radius is being modified. * \param [in] whichone Which circle parameter to modify. * * <B>whichone</B> can have the following values: * <DL> * <DT>*</DT><DD>CIRCLE_CENTER * <DT>*</DT><DD>CIRCLE_RADIUS * </DL> */ void geda_circle_object_modify (TOPLEVEL *toplevel, GedaObject *object, gint x, gint y, gint whichone) { o_emit_pre_change_notify (toplevel, object); switch(whichone) { case CIRCLE_CENTER: geda_circle_object_set_center_x (object, x); geda_circle_object_set_center_y (object, y); break; case CIRCLE_RADIUS: geda_circle_object_set_radius (object, x); break; default: break; } /* recalculate the boundings */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief recreate the graphics of a text object * \par Function Description * This function updates the underlying primary of the text object * \a o_current. * * \param toplevel The TOPLEVEL object * \param o_current The text object to update */ void o_text_recreate (TOPLEVEL *toplevel, OBJECT *o_current) { o_emit_pre_change_notify (toplevel, o_current); update_disp_string (o_current); o_current->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, o_current); }
/*! \brief Modify a BOX OBJECT's coordinates. * \par Function Description * This function modifies the coordinates of one of the four corner of * the box. The new coordinates of the corner identified by <B>whichone</B> * are given by <B>x</B> and <B>y</B> in world unit. * * The coordinates of the corner is modified in the world coordinate system. * Screen coordinates and boundings are then updated. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object BOX OBJECT to be modified. * \param [in] x x coordinate. * \param [in] y y coordinate. * \param [in] whichone coordinate to change. * * \note * <B>whichone</B> can take the following values: * <DL> * <DT>*</DT><DD>BOX_UPPER_LEFT * <DT>*</DT><DD>BOX_LOWER_LEFT * <DT>*</DT><DD>BOX_UPPER_RIGHT * <DT>*</DT><DD>BOX_LOWER_RIGHT * </DL> */ void geda_box_object_modify (TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { int tmp; o_emit_pre_change_notify (toplevel, object); /* change the position of the selected corner */ switch(whichone) { case BOX_UPPER_LEFT: object->box->upper_x = x; object->box->upper_y = y; break; case BOX_LOWER_LEFT: object->box->upper_x = x; object->box->lower_y = y; break; case BOX_UPPER_RIGHT: object->box->lower_x = x; object->box->upper_y = y; break; case BOX_LOWER_RIGHT: object->box->lower_x = x; object->box->lower_y = y; break; default: return; } /* need to update the upper left and lower right corners */ if(object->box->upper_x > object->box->lower_x) { tmp = object->box->upper_x; object->box->upper_x = object->box->lower_x; object->box->lower_x = tmp; } if(object->box->upper_y < object->box->lower_y) { tmp = object->box->upper_y; object->box->upper_y = object->box->lower_y; object->box->lower_y = tmp; } /* recalculate the world coords and the boundings */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief Set #OBJECT's fill options. * \par Function Description * This function allows an #OBJECT's fill options to be configured. * See #OBJECT_FILLING for information on valid fill types. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] o_current OBJECT to be updated. * \param [in] type OBJECT_FILLING type. * \param [in] width fill width. * \param [in] pitch1 cross hatch line distance * \param [in] angle1 cross hatch angle * \param [in] pitch2 cross hatch line distance * \param [in] angle2 cross hatch angle * */ void o_set_fill_options(TOPLEVEL *toplevel, OBJECT *o_current, OBJECT_FILLING type, int width, int pitch1, int angle1, int pitch2, int angle2) { if(o_current == NULL) { return; } /* do some error checking / correcting */ if (geda_fill_type_draw_first_hatch (type)) { if (width < 0) { width = 1; } if (angle1 < 0) { angle1 = 45; } if (pitch1 < 0) { pitch1 = 100; } } else { width = -1; angle1 = -1; pitch1 = -1; } if (geda_fill_type_draw_second_hatch (type)) { if (angle2 < 0) { angle2 = 135; } if (pitch2 < 0) { pitch2 = 100; } } else { angle2 = -1; pitch2 = -1; } o_emit_pre_change_notify (toplevel, o_current); o_current->fill_type = type; o_current->fill_width = width; o_current->fill_pitch1 = pitch1; o_current->fill_angle1 = angle1; o_current->fill_pitch2 = pitch2; o_current->fill_angle2 = angle2; o_emit_change_notify (toplevel, o_current); }
/*! \brief Modify a BOX OBJECT's coordinates. * \par Function Description * Modifies the coordinates of all four corners of \a box, by setting * the box to the rectangle enclosed by the points (\a x1, \a y1) and * (\a x2, \a y2). * * \param [in] toplevel current #TOPLEVEL. * \param [in,out] object box #OBJECT to be modified. * \param [in] x1 x coordinate of first corner of box. * \param [in] y1 y coordinate of first corner of box. * \param [in] x2 x coordinate of second corner of box. * \param [in] y2 y coordinate of second corner of box, */ void o_box_modify_all (TOPLEVEL *toplevel, OBJECT *object, int x1, int y1, int x2, int y2) { object->box->lower_x = (x1 > x2) ? x1 : x2; object->box->lower_y = (y1 > y2) ? y2 : y1; object->box->upper_x = (x1 > x2) ? x2 : x1; object->box->upper_y = (y1 > y2) ? y1 : y2; /* recalculate the world coords and bounds */ o_box_recalc(toplevel, object); o_emit_change_notify (toplevel, object); }
/* Called just before removing an OBJECT from a PAGE * or after appending an OBJECT to a PAGE. */ static void object_added (TOPLEVEL *toplevel, PAGE *page, OBJECT *object) { /* Set up object parent pointer */ #ifndef NDEBUG if (object->page != NULL) { g_critical ("Object %p already has parent page %p!", object, object->page); } #endif object->page = page; /* Update object connection tracking */ s_conn_update_object (page, object); o_emit_change_notify (toplevel, object); }
/*! \brief Modify a picture object's coordinates. * \par Function Description * Modifies the coordinates of all four corners of a picture \a * object. The picture is adjusted to fit the rectangle enclosed by * the points (\a x1, \a y1) and (\a x2, \a y2), and scaled as large * as possible to still fit within that rectangle. * * \param [in] toplevel current #TOPLEVEL. * \param [in,out] object picture #OBJECT to be modified. * \param [in] x1 x coordinate of first corner of box. * \param [in] y1 y coordinate of first corner of box. * \param [in] x2 x coordinate of second corner of box. * \param [in] y2 y coordinate of second corner of box. */ void o_picture_modify_all (TOPLEVEL *toplevel, OBJECT *object, int x1, int y1, int x2, int y2) { o_emit_pre_change_notify (toplevel, object); /* Normalise the requested rectangle. */ object->picture->lower_x = (x1 > x2) ? x1 : x2; object->picture->lower_y = (y1 > y2) ? y2 : y1; object->picture->upper_x = (x1 > x2) ? x2 : x1; object->picture->upper_y = (y1 > y2) ? y1 : y2; /* recalculate the world coords and bounds */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief Set an #OBJECT's line options. * \par Function Description * This function allows a line's end, type, width, length and space to be set. * See #OBJECT_END and #OBJECT_TYPE for information on valid * object end and type values. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] o_current OBJECT to set line options on. * \param [in] end An OBJECT_END. * \param [in] type An OBJECT_TYPE. * \param [in] width Line width. * \param [in] length Line length. * \param [in] space Spacing between dashes/dots. Cannot be negative. * * \todo Make space an unsigned int and check for a max value instead. * If a max value is not required, then it would simplify the code. */ void o_set_line_options(TOPLEVEL *toplevel, OBJECT *o_current, OBJECT_END end, OBJECT_TYPE type, int width, int length, int space) { g_return_if_fail (o_current != NULL); /* do some error checking / correcting */ switch(type) { case(TYPE_SOLID): length = -1; space = -1; break; case(TYPE_DOTTED): length = -1; if (space < 1) { space = 100; } break; case(TYPE_DASHED): case(TYPE_CENTER): case(TYPE_PHANTOM): if (length < 1) { length = 100; } if (space < 1) { space = 100; } break; default: break; } o_emit_pre_change_notify (toplevel, o_current); o_current->line_width = width; o_current->line_end = end; o_current->line_type = type; o_current->line_length = length; o_current->line_space = space; /* Recalculate the object's bounding box */ o_current->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, o_current); }
/*! \brief Set an #OBJECT's line options. * \par Function Description * This function allows a line's end, type, width, length and space to be set. * See #OBJECT_END and #OBJECT_TYPE for information on valid * object end and type values. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] o_current OBJECT to set line options on. * \param [in] end An OBJECT_END. * \param [in] type An OBJECT_TYPE. * \param [in] width Line width. * \param [in] length Line length. * \param [in] space Spacing between dashes/dots. Cannot be negative. * * \todo Make space an unsigned int and check for a max value instead. * If a max value is not required, then it would simplify the code. */ void o_set_line_options(TOPLEVEL *toplevel, OBJECT *o_current, OBJECT_END end, OBJECT_TYPE type, int width, int length, int space) { if(o_current == NULL) { return; } /* do some error checking / correcting */ switch(type) { case(TYPE_DOTTED): if (space < 1) { space = 100; s_log_message (_("Invalid space specified, setting to 100\n")); } break; case(TYPE_DASHED): case(TYPE_CENTER): case(TYPE_PHANTOM): if (length < 1) { length = 100; s_log_message (_("Invalid length specified, setting to 100\n")); } if (space < 1) { space = 100; s_log_message (_("Invalid space specified, setting to 100\n")); } break; default: break; } o_emit_pre_change_notify (toplevel, o_current); o_current->line_width = width; o_current->line_end = end; o_current->line_type = type; o_current->line_length = length; o_current->line_space = space; /* Recalculate the object's bounding box */ o_recalc_single_object( toplevel, o_current ); o_emit_change_notify (toplevel, o_current); }
/*! \brief Set a picture object's contents from a buffer. * \par Function Description * Sets the contents of the picture \a object by reading image data * from a buffer. The buffer should be in on-disk format. * * \param toplevel The current #TOPLEVEL. * \param object The picture #OBJECT to modify. * \param filename The new filename for the picture. * \param data The new image data buffer. * \param len The size of the data buffer. * \param error Location to return error information. * \return TRUE on success, FALSE on failure. */ gboolean o_picture_set_from_buffer (TOPLEVEL *toplevel, OBJECT *object, const gchar *filename, const gchar *data, size_t len, GError **error) { GdkPixbuf *pixbuf; GInputStream *stream; gchar *tmp; g_return_val_if_fail (toplevel != NULL, FALSE); g_return_val_if_fail (object != NULL, FALSE); g_return_val_if_fail (object->picture != NULL, FALSE); g_return_val_if_fail (data != NULL, FALSE); /* Check that we can actually load the data before making any * changes to the object. */ stream = G_INPUT_STREAM (g_memory_input_stream_new_from_data (data, len, NULL)); pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error); g_object_unref (stream); if (pixbuf == NULL) return FALSE; o_emit_pre_change_notify (toplevel, object); if (object->picture->pixbuf != NULL) { g_object_unref (object->picture->pixbuf); } object->picture->pixbuf = pixbuf; object->picture->ratio = ((double) gdk_pixbuf_get_width(pixbuf) / gdk_pixbuf_get_height(pixbuf)); tmp = g_strdup (filename); g_free (object->picture->filename); object->picture->filename = tmp; gchar *buf = (gchar*) g_realloc (object->picture->file_content, len); /* It's possible that these buffers might overlap, because the * library user hates us. */ memmove (buf, data, len); object->picture->file_content = buf; object->picture->file_length = len; o_emit_change_notify (toplevel, object); return TRUE; }
/*! \brief Sets the type, and corresponding width of a pin * * \par Function Description * Sets the pin's type and width to a particular style. * * \param [in] toplevel The TOPLEVEL object * \param [in] o_current The pin OBJECT being modified * \param [in] pin_type The new type of this pin */ void o_pin_set_type (TOPLEVEL *toplevel, OBJECT *o_current, int pin_type) { o_emit_pre_change_notify (toplevel, o_current); switch (pin_type) { default: g_critical ("o_pin_set_type: Got invalid pin type %i\n", pin_type); /* Fall through */ case PIN_TYPE_NET: o_current->line_width = PIN_WIDTH_NET; o_current->pin_type = PIN_TYPE_NET; break; case PIN_TYPE_BUS: o_current->line_width = PIN_WIDTH_BUS; o_current->pin_type = PIN_TYPE_BUS; break; } o_emit_change_notify (toplevel, o_current); }
/*! \brief Modify controol point location * * \par Function Description * This function modifies a control point location of the path object * *object. The control point being modified is selected according to * the whichone parameter. * * The new position is given by <B>x</B> and <B>y</B>. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object The path OBJECT * \param [in] x New x coordinate for the control point * \param [in] y New y coordinate for the control point * \param [in] whichone Which control point is being modified */ void geda_path_object_modify (TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { int i; int grip_no = 0; PATH_SECTION *section; o_emit_pre_change_notify (toplevel, object); for (i = 0; i < object->path->num_sections; i++) { section = &object->path->sections[i]; switch (section->code) { case PATH_CURVETO: /* Two control point grips */ if (whichone == grip_no++) { section->x1 = x; section->y1 = y; } if (whichone == grip_no++) { section->x2 = x; section->y2 = y; } /* Fall through */ case PATH_MOVETO: case PATH_MOVETO_OPEN: case PATH_LINETO: /* Destination point grip */ if (whichone == grip_no++) { section->x3 = x; section->y3 = y; } break; case PATH_END: break; } } /* Update bounding box */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief Set #OBJECT's fill options. * \par Function Description * This function allows an #OBJECT's fill options to be configured. * See #OBJECT_FILLING for information on valid fill types. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] o_current OBJECT to be updated. * \param [in] type OBJECT_FILLING type. * \param [in] width fill width. * \param [in] pitch1 cross hatch line distance * \param [in] angle1 cross hatch angle * \param [in] pitch2 cross hatch line distance * \param [in] angle2 cross hatch angle * */ void o_set_fill_options(TOPLEVEL *toplevel, OBJECT *o_current, OBJECT_FILLING type, int width, int pitch1, int angle1, int pitch2, int angle2) { if(o_current == NULL) { return; } o_emit_pre_change_notify (toplevel, o_current); o_current->fill_type = type; o_current->fill_width = width; o_current->fill_pitch1 = pitch1; o_current->fill_angle1 = angle1; o_current->fill_pitch2 = pitch2; o_current->fill_angle2 = angle2; o_emit_change_notify (toplevel, o_current); }
/*! \brief * \par Function Description * This function modifies the internal values of the arc object * *object according to the whichone parameter. * * The new values are given by <B>x</B> and/or <B>y</B>. Their meaning depends on the value of whichone. * * If <B>whichone</B> is equal to #ARC_CENTER, the (<B>x</B>,<B>y</B>) point is taken as the new center * of the arc in world unit. * * If <B>whichone</B> is equal to #ARC_RADIUS, the <B>x</B> parameter is taken to be the radius * of the arc in world unit. The <B>y</B> parameter is ignored. * * If <B>whichone</B> is equal to #ARC_START_ANGLE, the <B>x</B> parameter is the starting angle of the arc. * <B>x</B> is in degrees. <B>y</B> is ignored. * * If <B>whichone</B> is equal to #ARC_END_ANGLE, the <B>x</B> parameter is the ending angle of the arc. * <B>x</B> is in degrees. <B>y</B> is ignored. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object * \param [in] x * \param [in] y * \param [in] whichone */ void o_arc_modify(TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { o_emit_pre_change_notify (toplevel, object); switch(whichone) { case ARC_CENTER: /* modify the center of arc object */ object->arc->x = x; object->arc->y = y; break; case ARC_RADIUS: /* modify the radius of arc object */ object->arc->width = 2 * x; object->arc->height = 2 * x; break; case ARC_START_ANGLE: /* modify the start angle of the arc object */ object->arc->start_angle = x; break; case ARC_END_ANGLE: /* modify the end angle of the arc object */ object->arc->end_angle = x; break; default: break; } /* update the screen coords and the bounding box */ o_arc_recalc(toplevel, object); o_emit_change_notify (toplevel, object); }
/*! \brief * \par Function Description * This function modifies the internal values of the arc object * *object according to the whichone parameter. * * The new values are given by <B>x</B> and/or <B>y</B>. Their meaning depends on the value of whichone. * * If <B>whichone</B> is equal to #ARC_CENTER, the (<B>x</B>,<B>y</B>) point is taken as the new center * of the arc in world unit. * * If <B>whichone</B> is equal to #ARC_RADIUS, the <B>x</B> parameter is taken to be the radius * of the arc in world unit. The <B>y</B> parameter is ignored. * * If <B>whichone</B> is equal to #ARC_START_ANGLE, the <B>x</B> parameter is the starting angle of the arc. * <B>x</B> is in degrees. <B>y</B> is ignored. * * If <B>whichone</B> is equal to #ARC_SWEEP_ANGLE, the <B>x</B> parameter is the ending angle of the arc. * <B>x</B> is in degrees. <B>y</B> is ignored. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object * \param [in] x * \param [in] y * \param [in] whichone */ void geda_arc_object_modify (TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { o_emit_pre_change_notify (toplevel, object); switch(whichone) { case ARC_CENTER: /* modify the center of arc object */ object->arc->x = x; object->arc->y = y; break; case ARC_RADIUS: /* modify the radius of arc object */ object->arc->radius = x; break; case ARC_START_ANGLE: /* modify the start angle of the arc object */ object->arc->start_angle = x; break; case ARC_SWEEP_ANGLE: /* modify the end angle of the arc object */ object->arc->sweep_angle = x; break; default: break; } /* update the screen coords and the bounding box */ object->w_bounds_valid_for = NULL; o_emit_change_notify (toplevel, object); }
/*! \brief Modify the description of a picture OBJECT. * \par Function Description * This function modifies the coordinates of one of the four corner of * the picture. The new coordinates of the corner identified by * <B>whichone</B> are given by <B>x</B> and <B>y</B> in world unit. * * The coordinates of the corner is modified in the world coordinate system. * Screen coordinates and boundings are then updated. * * \param [in] toplevel The TOPLEVEL object. * \param [in,out] object Picture OBJECT to modify. * \param [in] x New x coordinate. * \param [in] y New y coordinate. * \param [in] whichone Which picture parameter to modify. * * <B>whichone</B> can have the following values: * <DL> * <DT>*</DT><DD>PICTURE_UPPER_LEFT * <DT>*</DT><DD>PICTURE_LOWER_LEFT * <DT>*</DT><DD>PICTURE_UPPER_RIGHT * <DT>*</DT><DD>PICTURE_LOWER_RIGHT * </DL> */ void o_picture_modify(TOPLEVEL *toplevel, OBJECT *object, int x, int y, int whichone) { int tmp; o_emit_pre_change_notify (toplevel, object); /* change the position of the selected corner */ switch(whichone) { case PICTURE_UPPER_LEFT: object->picture->upper_x = x; tmp = abs(object->picture->upper_x - object->picture->lower_x) / object->picture->ratio; if (y < object->picture->lower_y) { tmp = -tmp; } object->picture->upper_y = object->picture->lower_y + tmp; break; case PICTURE_LOWER_LEFT: object->picture->upper_x = x; tmp = abs(object->picture->upper_x - object->picture->lower_x) / object->picture->ratio; if (y > object->picture->upper_y) { tmp = -tmp; } object->picture->lower_y = object->picture->upper_y - tmp; break; case PICTURE_UPPER_RIGHT: object->picture->lower_x = x; tmp = abs(object->picture->upper_x - object->picture->lower_x) / object->picture->ratio; if (y < object->picture->lower_y) { tmp = -tmp; } object->picture->upper_y = object->picture->lower_y + tmp; break; case PICTURE_LOWER_RIGHT: object->picture->lower_x = x; tmp = abs(object->picture->upper_x - object->picture->lower_x) / object->picture->ratio; if (y > object->picture->upper_y) { tmp = -tmp; } object->picture->lower_y = object->picture->upper_y - tmp; break; default: return; } /* need to update the upper left and lower right corners */ if(object->picture->upper_x > object->picture->lower_x) { tmp = object->picture->upper_x; object->picture->upper_x = object->picture->lower_x; object->picture->lower_x = tmp; } if(object->picture->upper_y < object->picture->lower_y) { tmp = object->picture->upper_y; object->picture->upper_y = object->picture->lower_y; object->picture->lower_y = tmp; } /* recalculate the screen coords and the boundings */ o_picture_recalc(toplevel, object); o_emit_change_notify (toplevel, object); }