/*! \brief Change visibility status of attribute object. * \par Function Description * This function toggles the visibility status of the attribute \a * object and updates it. The object is erased or redrawn if * necessary. * * \param [in] w_current The GschemToplevel object. * \param [in] object The attribute object. */ void o_attrib_toggle_visibility(GschemToplevel *w_current, OBJECT *object) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); g_return_if_fail (object != NULL && object->type == OBJ_TEXT); if (o_is_visible (object)) { /* only erase if we are not showing hidden text */ if (!toplevel->show_hidden_text) { o_invalidate (w_current, object); } o_set_visibility (toplevel, object, INVISIBLE); if (toplevel->show_hidden_text) { /* draw text so that little I is drawn */ o_invalidate (w_current, object); } } else { /* if we are in the special show hidden mode, then erase text first */ /* to get rid of the little I */ if (toplevel->show_hidden_text) { o_invalidate (w_current, object); } o_set_visibility (toplevel, object, VISIBLE); o_text_recreate(toplevel, object); } gschem_toplevel_page_content_changed (w_current, toplevel->page_current); }
/*! \brief Replace all selected pictures with a new picture * \par Function Description * Replaces all pictures in the current selection with a new image. * * \param [in] w_current The GschemToplevel object * \param [in] filename The filename of the new picture * \param [out] error The location to return error information. * \return TRUE on success, FALSE on failure. */ gboolean o_picture_exchange (GschemToplevel *w_current, const gchar *filename, GError **error) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); GList *iter; for (iter = geda_list_get_glist (toplevel->page_current->selection_list); iter != NULL; iter = g_list_next (iter)) { OBJECT *object = (OBJECT *) iter->data; g_assert (object != NULL); if (object->type == OBJ_PICTURE) { gboolean status; /* Erase previous picture */ o_invalidate (w_current, object); status = o_picture_set_from_file (toplevel, object, filename, error); if (!status) return FALSE; /* Draw new picture */ o_invalidate (w_current, object); } } return TRUE; }
/*! \brief Set what part of an attribute is shown. * \par Function Description * This function changes what part (name, value or both) of an * attribute is shown by its attribute object. The attribute object * is erased, updated and finally redrawn. * * \param [in] w_current The GschemToplevel object. * \param [in] object The attribute object. * \param [in] show_name_value The new display flag for attribute. */ void o_attrib_toggle_show_name_value(GschemToplevel *w_current, OBJECT *object, int show_name_value) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); g_return_if_fail (object != NULL && object->type == OBJ_TEXT); o_invalidate (w_current, object); object->show_name_value = show_name_value; o_text_recreate(toplevel, object); gschem_toplevel_page_content_changed (w_current, toplevel->page_current); }
/*! \brief Set what part of an attribute is shown. * \par Function Description * This function changes what part (name, value or both) of an * attribute is shown by its attribute object. The attribute object * is erased, updated and finally redrawn. * * \param [in] w_current The GSCHEM_TOPLEVEL object. * \param [in] object The attribute object. * \param [in] show_name_value The new display flag for attribute. */ void o_attrib_toggle_show_name_value(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int show_name_value) { TOPLEVEL *toplevel = w_current->toplevel; g_return_if_fail (object != NULL && object->type == OBJ_TEXT); o_invalidate (w_current, object); object->show_name_value = show_name_value; o_text_recreate(toplevel, object); toplevel->page_current->CHANGED = 1; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_move_start(GschemToplevel *w_current, int w_x, int w_y) { GList *s_iter; g_return_if_fail (w_current != NULL); GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); g_return_if_fail (page_view != NULL); PAGE *page = gschem_page_view_get_page (page_view); g_return_if_fail (page != NULL); g_return_if_fail (w_current->stretch_list == NULL); if (o_select_selected (w_current)) { i_set_state (w_current, MOVEMODE); gboolean net_rubber_band_mode; net_rubber_band_mode = gschem_options_get_net_rubber_band_mode (w_current->options); w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE; w_current->first_wx = w_current->second_wx = w_x; w_current->first_wy = w_current->second_wy = w_y; o_invalidate_glist (w_current, geda_list_get_glist (page->selection_list)); if (net_rubber_band_mode) { o_move_prep_rubberband(w_current); /* Set the dont_redraw flag on rubberbanded objects and invalidate them. * This ensures that they are not drawn (in their un-stretched position) * during screen updates. */ for (s_iter = w_current->stretch_list; s_iter != NULL; s_iter = g_list_next (s_iter)) { STRETCH *stretch = s_iter->data; stretch->object->dont_redraw = TRUE; o_invalidate (w_current, stretch->object); } } o_select_move_to_place_list(w_current); i_action_start (w_current); o_move_invalidate_rubber (w_current, TRUE); } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_slot_end(GSCHEM_TOPLEVEL *w_current, const char *string, int len) { TOPLEVEL *toplevel = w_current->toplevel; OBJECT *new_obj; OBJECT *object; OBJECT *temp; char *slot_value; char *numslots_value; OBJECT *slot_text_object; char *value = NULL; int numslots; int new_slot_number; int status; status = o_attrib_get_name_value(string, NULL, &value); if (!status) { s_log_message(_("Slot attribute malformed\n")); return; } object = o_select_return_first_object(w_current); /* get the parent object if the selection is only a text object */ if (object != NULL && object->type == OBJ_TEXT) { if (object->attached_to != NULL) { object = object->attached_to; } } /* now find the slot attribute on the outside first */ if (object != NULL) { numslots_value = o_attrib_search_numslots(object, NULL); if (!numslots_value) { s_log_message(_("numslots attribute missing\n")); s_log_message( _("Slotting not allowed for this component\n")); g_free(value); return; } numslots = atoi(numslots_value); g_free(numslots_value); new_slot_number = atoi(value); #if DEBUG printf("numslots = %d\n", numslots); #endif if (new_slot_number > numslots || new_slot_number <=0 ) { s_log_message(_("New slot number out of range\n")); g_free(value); return; } /* first see if slot attribute already exists outside * complex */ slot_value = o_attrib_search_slot(object, &slot_text_object); if (slot_value) { o_text_set_string (toplevel, slot_text_object, string); temp = slot_text_object; if (temp->visibility == VISIBLE || (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) { o_invalidate (w_current,temp); } o_text_recreate(toplevel, temp); /* this doesn't deal with the selection list * item */ if (temp->visibility == VISIBLE || (temp->visibility == INVISIBLE && toplevel->show_hidden_text)) { o_invalidate (w_current,temp); } g_free(slot_value); } else { /* here you need to do the add the slot attribute since it doesn't exist */ new_obj = o_text_new (toplevel, OBJ_TEXT, ATTRIBUTE_COLOR, object->complex->x, object->complex->y, LOWER_LEFT, 0, /* zero is angle */ string, 10, INVISIBLE, SHOW_NAME_VALUE); s_page_append (toplevel->page_current, new_obj); /* manually attach attribute */ o_attrib_attach (toplevel, new_obj, object, FALSE); slot_text_object = new_obj; } o_invalidate (w_current, object); o_attrib_slot_update(toplevel, object); o_invalidate (w_current,object); toplevel->page_current->CHANGED = 1; g_free(value); } else { fprintf(stderr, _("uggg! you tried to slot edit something that doesn't exist!\n")); g_free(value); exit(-1); } }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ int o_net_add_busrippers(GSCHEM_TOPLEVEL *w_current, OBJECT *net_obj, GList *prev_conn_objects) { TOPLEVEL *toplevel = w_current->toplevel; OBJECT *new_obj; int color; GList *cl_current = NULL; OBJECT *bus_object = NULL; CONN *found_conn = NULL; int done; int otherone; BUS_RIPPER rippers[2]; int ripper_count = 0; int i; double length; int sign; double distance1, distance2; int first, second; int made_changes = FALSE; const int ripper_size = w_current->bus_ripper_size; int complex_angle = 0; const CLibSymbol *rippersym = NULL; length = o_line_length(net_obj); if (!prev_conn_objects) { return(FALSE); } if (length <= ripper_size) { return(FALSE); } if (toplevel->override_net_color == -1) { color = NET_COLOR; } else { color = toplevel->override_net_color; } /* check for a bus connection and draw rippers if so */ cl_current = prev_conn_objects; while (cl_current != NULL) { bus_object = (OBJECT *) cl_current->data; if (bus_object && bus_object->type == OBJ_BUS) { /* yes, using the net routine is okay */ int bus_orientation = o_net_orientation(bus_object); int net_orientation = o_net_orientation(net_obj); /* find the CONN structure which is associated with this object */ GList *cl_current2 = net_obj->conn_list; done = FALSE; while (cl_current2 != NULL && !done) { CONN *tmp_conn = (CONN *) cl_current2->data; if (tmp_conn && tmp_conn->other_object && tmp_conn->other_object == bus_object) { found_conn = tmp_conn; done = TRUE; } cl_current2 = g_list_next(cl_current2); } if (!found_conn) { return(FALSE); } otherone = !found_conn->whichone; /* now deal with the found connection */ if (bus_orientation == HORIZONTAL && net_orientation == VERTICAL) { /* printf("found horiz bus %s %d!\n", bus_object->name, found_conn->whichone);*/ sign = bus_object->bus_ripper_direction; if (!sign) { if (bus_object->line->x[0] < bus_object->line->x[1]) { first = 0; second = 1; } else { first = 1; second = 0; } distance1 = abs(bus_object->line->x[first] - net_obj->line->x[found_conn->whichone]); distance2 = abs(bus_object->line->x[second] - net_obj->line->x[found_conn->whichone]); if (distance1 <= distance2) { sign = 1; } else { sign = -1; } bus_object->bus_ripper_direction = sign; } /* printf("hor sign: %d\n", sign); */ if (net_obj->line->y[otherone] < bus_object->line->y[0]) { /* new net is below bus */ /*printf("below\n");*/ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 0; } else { complex_angle = 90; } } else { /* symmetric */ complex_angle = 0; } net_obj->line->y[found_conn->whichone] -= ripper_size; o_recalc_single_object(toplevel, net_obj); rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + sign*ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + ripper_size; ripper_count++; /* printf("done\n"); */ made_changes++; } else { /* new net is above bus */ /* printf("above\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 270; } else { complex_angle = 180; } } else { /* symmetric */ complex_angle = 180; } net_obj->line->y[found_conn->whichone] += ripper_size; o_recalc_single_object(toplevel, net_obj); rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + sign*ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] - ripper_size; ripper_count++; /* printf("done\n"); */ made_changes++; } } else if (bus_orientation == VERTICAL && net_orientation == HORIZONTAL) { /* printf("found vert bus %s %d!\n", bus_object->name, found_conn->whichone); */ sign = bus_object->bus_ripper_direction; if (!sign) { if (bus_object->line->y[0] < bus_object->line->y[1]) { first = 0; second = 1; } else { first = 1; second = 0; } distance1 = abs(bus_object->line->y[first] - net_obj->line->y[found_conn->whichone]); distance2 = abs(bus_object->line->y[second] - net_obj->line->y[found_conn->whichone]); if (distance1 <= distance2) { sign = 1; } else { sign = -1; } bus_object->bus_ripper_direction = sign; } /* printf("ver sign: %d\n", sign); */ if (net_obj->line->x[otherone] < bus_object->line->x[0]) { /* new net is to the left of the bus */ /* printf("left\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 0; } else { complex_angle = 270; } } else { /* symmetric */ complex_angle = 270; } net_obj->line->x[found_conn->whichone] -= ripper_size; o_recalc_single_object(toplevel, net_obj); rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] + ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + sign*ripper_size; ripper_count++; made_changes++; } else { /* new net is to the right of the bus */ /* printf("right\n"); */ if (ripper_count >= 2) { /* try to exit gracefully */ fprintf(stderr, _("Tried to add more than two bus rippers. Internal gschem error.\n")); made_changes = FALSE; break; } if (w_current->bus_ripper_rotation == NON_SYMMETRIC) { /* non-symmetric */ if (sign == 1) { complex_angle = 90; } else { complex_angle = 180; } } else { /* symmetric */ complex_angle = 90; } net_obj->line->x[found_conn->whichone] += ripper_size; o_recalc_single_object(toplevel, net_obj); rippers[ripper_count].x[0] = net_obj->line->x[found_conn->whichone]; rippers[ripper_count].y[0] = net_obj->line->y[found_conn->whichone]; rippers[ripper_count].x[1] = net_obj->line->x[found_conn->whichone] - ripper_size; rippers[ripper_count].y[1] = net_obj->line->y[found_conn->whichone] + sign*ripper_size; ripper_count++; made_changes++; } } } cl_current = g_list_next(cl_current); } if (made_changes) { s_conn_remove_object (toplevel, net_obj); if (w_current->bus_ripper_type == COMP_BUS_RIPPER) { GList *symlist = s_clib_search (toplevel->bus_ripper_symname, CLIB_EXACT); if (symlist != NULL) { rippersym = (CLibSymbol *) symlist->data; } g_list_free (symlist); } for (i = 0; i < ripper_count; i++) { if (w_current->bus_ripper_type == NET_BUS_RIPPER) { new_obj = o_net_new(toplevel, OBJ_NET, color, rippers[i].x[0], rippers[i].y[0], rippers[i].x[1], rippers[i].y[1]); s_page_append (toplevel->page_current, new_obj); } else { if (rippersym != NULL) { new_obj = o_complex_new (toplevel, OBJ_COMPLEX, DEFAULT_COLOR, rippers[i].x[0], rippers[i].y[0], complex_angle, 0, rippersym, toplevel->bus_ripper_symname, 1); s_page_append_list (toplevel->page_current, o_complex_promote_attribs (toplevel, new_obj)); s_page_append (toplevel->page_current, new_obj); o_invalidate (w_current, new_obj); } else { s_log_message(_("Bus ripper symbol [%s] was not found in any component library\n"), toplevel->bus_ripper_symname); } } } s_conn_update_object (toplevel, net_obj); return(TRUE); } return(FALSE); }
/*! \brief finish a net drawing action * \par Function Description * This function finishes the drawing of a net. If we have a visible * magnetic marker, we use that instead of the current cursor * position. * * The rubber nets are removed, the nets and cues are drawn and the * net is added to the TOPLEVEL structure. * * The function returns TRUE if it has drawn a net, FALSE otherwise. */ int o_net_end(GSCHEM_TOPLEVEL *w_current, int w_x, int w_y) { TOPLEVEL *toplevel = w_current->toplevel; int color; int primary_zero_length, secondary_zero_length; int found_primary_connection = FALSE; int save_wx, save_wy; GList *prev_conn_objects = NULL; OBJECT *new_net = NULL; g_assert( w_current->inside_action != 0 ); o_net_invalidate_rubber (w_current); if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) o_net_finishmagnetic(w_current); w_current->rubber_visible = 0; /* See if either of the nets are zero length. We'll only add */ /* the non-zero ones */ primary_zero_length = (w_current->first_wx == w_current->second_wx) && (w_current->first_wy == w_current->second_wy); secondary_zero_length = (w_current->second_wx == w_current->third_wx) && (w_current->second_wy == w_current->third_wy); /* If both nets are zero length... */ /* this ends the net drawing behavior */ if ( primary_zero_length && secondary_zero_length ) { return FALSE; } save_wx = w_current->third_wx; save_wy = w_current->third_wy; if (toplevel->override_net_color == -1) { color = NET_COLOR; } else { color = toplevel->override_net_color; } if (w_current->third_wx != snap_grid (w_current, w_current->third_wx) || w_current->third_wy != snap_grid (w_current, w_current->third_wy)) s_log_message(_("Warning: Ending net at off grid coordinate\n")); if (!primary_zero_length ) { /* create primary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->first_wx, w_current->first_wy, w_current->second_wx, w_current->second_wy); s_page_append (toplevel->page_current, new_net); /* conn stuff */ /* LEAK CHECK 1 */ prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) { g_list_free (prev_conn_objects); prev_conn_objects = NULL; prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); } #if DEBUG printf("primary:\n"); s_conn_print(new_net->conn_list); #endif o_invalidate (w_current, new_net); o_invalidate_glist (w_current, prev_conn_objects); g_list_free (prev_conn_objects); prev_conn_objects = NULL; /* Go off and search for valid connection on this newly created net */ found_primary_connection = s_conn_net_search(new_net, 1, new_net->conn_list); if (found_primary_connection) { /* if a net connection is found, reset start point of next net */ save_wx = w_current->second_wx; save_wy = w_current->second_wy; } /* you don't want to consolidate nets which are drawn non-ortho */ if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) { /* CAUTION: Object list will change when nets are consolidated, don't * keep pointers to other objects than new_net after this. */ o_net_consolidate_segments(toplevel, new_net); } } /* If the second net is not zero length, add it as well */ /* Also, a valid net connection from the primary net was not found */ if (!secondary_zero_length && !found_primary_connection) { /* Add secondary net */ new_net = o_net_new(toplevel, OBJ_NET, color, w_current->second_wx, w_current->second_wy, w_current->third_wx, w_current->third_wy); s_page_append (toplevel->page_current, new_net); /* conn stuff */ /* LEAK CHECK 2 */ prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); if (o_net_add_busrippers (w_current, new_net, prev_conn_objects)) { g_list_free (prev_conn_objects); prev_conn_objects = NULL; prev_conn_objects = s_conn_return_others (prev_conn_objects, new_net); } #if DEBUG s_conn_print(new_net->conn_list); #endif o_invalidate (w_current, new_net); o_invalidate_glist (w_current, prev_conn_objects); g_list_free (prev_conn_objects); prev_conn_objects = NULL; /* you don't want to consolidate nets which are drawn non-ortho */ if (toplevel->net_consolidate == TRUE && !w_current->CONTROLKEY) { /* CAUTION: Object list will change when nets are consolidated, don't * keep pointers to other objects than new_net after this. */ o_net_consolidate_segments(toplevel, new_net); } } toplevel->page_current->CHANGED = 1; w_current->first_wx = save_wx; w_current->first_wy = save_wy; o_undo_savestate(w_current, UNDO_ALL); return (TRUE); }
/*! \brief Add a component to the page. * \par Function Description * Adds a component <B>scm_comp_name</B> to the schematic, at * position (<B>scm_x</B>, <B>scm_y</B>), with some properties set by * the parameters: * \param [in] scm_x Coordinate X of the symbol. * \param [in] scm_y Coordinate Y of the symbol. * \param [in] angle Angle of rotation of the symbol. * \param [in] selectable True if the symbol is selectable, false otherwise. * \param [in] mirror True if the symbol is mirrored, false otherwise. * If scm_comp_name is a scheme empty list, SCM_BOOL_F, or an empty * string (""), then g_add_component returns SCM_BOOL_F without writing * to the log. * \return TRUE if the component was added, FALSE otherwise. * */ SCM g_add_component(SCM page_smob, SCM scm_comp_name, SCM scm_x, SCM scm_y, SCM scm_angle, SCM scm_selectable, SCM scm_mirror) { TOPLEVEL *toplevel; PAGE *page; gboolean selectable, mirror; gchar *comp_name; int x, y, angle; OBJECT *new_obj; const CLibSymbol *clib; /* Return if scm_comp_name is NULL (an empty list) or scheme's FALSE */ if (SCM_NULLP(scm_comp_name) || (SCM_BOOLP(scm_comp_name) && !(SCM_NFALSEP(scm_comp_name))) ) { return SCM_BOOL_F; } /* Get toplevel and the page */ SCM_ASSERT (g_get_data_from_page_smob (page_smob, &toplevel, &page), page_smob, SCM_ARG1, "add-component-at-xy"); /* Check the arguments */ SCM_ASSERT (scm_is_string(scm_comp_name), scm_comp_name, SCM_ARG2, "add-component-at-xy"); SCM_ASSERT ( scm_is_integer(scm_x), scm_x, SCM_ARG3, "add-component-at-xy"); SCM_ASSERT ( scm_is_integer(scm_y), scm_y, SCM_ARG4, "add-component-at-xy"); SCM_ASSERT ( scm_is_integer(scm_angle), scm_angle, SCM_ARG5, "add-component-at-xy"); SCM_ASSERT ( scm_boolean_p(scm_selectable), scm_selectable, SCM_ARG6, "add-component-at-xy"); SCM_ASSERT ( scm_boolean_p(scm_mirror), scm_mirror, SCM_ARG7, "add-component-at-xy"); /* Get the parameters */ comp_name = SCM_STRING_CHARS(scm_comp_name); x = scm_to_int(scm_y); y = scm_to_int(scm_y); angle = scm_to_int(scm_angle); selectable = SCM_NFALSEP(scm_selectable); mirror = SCM_NFALSEP(scm_mirror); SCM_ASSERT (comp_name, scm_comp_name, SCM_ARG2, "add-component-at-xy"); if (strcmp(comp_name, "") == 0) { return SCM_BOOL_F; } clib = s_clib_get_symbol_by_name (comp_name); new_obj = o_complex_new (toplevel, 'C', DEFAULT_COLOR, x, y, angle, mirror, clib, comp_name, selectable); s_page_append_list (page, o_complex_promote_attribs (toplevel, new_obj)); s_page_append (page, new_obj); /* * For now, do not redraw the newly added complex, since this might cause * flicker if you are zoom/panning right after this function executes */ #if 0 /* Now the new component should be added to the object's list and drawn in the screen */ o_invalidate (toplevel, new_object); #endif return SCM_BOOL_T; }
/* * Sets several text properties of the given <B>attribute smob</B>: - <B>coloridx</B>: The index of the text color, or -1 to keep previous color. - <B>size</B>: Size (numeric) of the text, or -1 to keep the previous size. - <B>alignment</B>: String with the alignment of the text. Possible values are: * "" : Keep the previous alignment. * "Lower Left" * "Middle Left" * "Upper Left" * "Lower Middle" * "Middle Middle" * "Upper Middle" * "Lower Right" * "Middle Right" * "Upper Right" - <B>rotation</B>: Angle of the text, or -1 to keep previous angle. - <B>x</B>, <B>y</B>: Coords of the text. */ SCM g_set_attrib_text_properties(SCM attrib_smob, SCM scm_coloridx, SCM scm_size, SCM scm_alignment, SCM scm_rotation, SCM scm_x, SCM scm_y) { struct st_attrib_smob *attribute = (struct st_attrib_smob *)SCM_CDR(attrib_smob); OBJECT *object; GSCHEM_TOPLEVEL *w_current = global_window_current; TOPLEVEL *toplevel = w_current->toplevel; int color = -1; int size = -1; char *alignment_string; int alignment = -2; int rotation = 0; int x = -1, y = -1; SCM_ASSERT (scm_is_integer(scm_coloridx), scm_coloridx, SCM_ARG2, "set-attribute-text-properties!"); SCM_ASSERT ( scm_is_integer(scm_size), scm_size, SCM_ARG3, "set-attribute-text-properties!"); SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment, SCM_ARG4, "set-attribute-text-properties!"); SCM_ASSERT ( scm_is_integer(scm_rotation), scm_rotation, SCM_ARG5, "set-attribute-text-properties!"); SCM_ASSERT ( scm_is_integer(scm_x), scm_x, SCM_ARG6, "set-attribute-text-properties!"); SCM_ASSERT ( scm_is_integer(scm_y), scm_y, SCM_ARG7, "set-attribute-text-properties!"); color = scm_to_int(scm_coloridx); SCM_ASSERT (!(color < -1 || color >= MAX_COLORS), scm_coloridx, SCM_ARG2, "set-attribute-text-properties!"); size = scm_to_int(scm_size); rotation = scm_to_int(scm_rotation); x = scm_to_int(scm_x); y = scm_to_int(scm_y); alignment_string = SCM_STRING_CHARS(scm_alignment); if (strlen(alignment_string) == 0) { alignment = -1; } if (strcmp(alignment_string, "Lower Left") == 0) { alignment = 0; } if (strcmp(alignment_string, "Middle Left") == 0) { alignment = 1; } if (strcmp(alignment_string, "Upper Left") == 0) { alignment = 2; } if (strcmp(alignment_string, "Lower Middle") == 0) { alignment = 3; } if (strcmp(alignment_string, "Middle Middle") == 0) { alignment = 4; } if (strcmp(alignment_string, "Upper Middle") == 0) { alignment = 5; } if (strcmp(alignment_string, "Lower Right") == 0) { alignment = 6; } if (strcmp(alignment_string, "Middle Right") == 0) { alignment = 7; } if (strcmp(alignment_string, "Upper Right") == 0) { alignment = 8; } if (alignment == -2) { /* Bad specified */ SCM_ASSERT (scm_is_string(scm_alignment), scm_alignment, SCM_ARG4, "set-attribute-text-properties!"); } if (attribute && attribute->attribute) { object = attribute->attribute; if (object && object->text) { o_invalidate (w_current, object); if (x != -1) { object->text->x = x; } if (y != -1) { object->text->y = y; } if (size != -1) { object->text->size = size; } if (alignment != -1) { object->text->alignment = alignment; } if (rotation != -1) { object->text->angle = rotation; } o_text_recreate(toplevel, object); if (!toplevel->DONT_REDRAW) { o_invalidate (w_current, object); } } } return SCM_BOOL_T; }