gschem
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gschem - gEDA Schematic Capture 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 #include <config.h> 00021 00022 #include <stdio.h> 00023 #include <sys/stat.h> 00024 #include <math.h> 00025 #ifdef HAVE_STRING_H 00026 #include <string.h> 00027 #endif 00028 #ifdef HAVE_UNISTD_H 00029 #include <unistd.h> 00030 #endif 00031 00032 #include "gschem.h" 00033 00034 #ifdef HAVE_LIBDMALLOC 00035 #include <dmalloc.h> 00036 #endif 00037 00038 #define MINIMUM_MARK_SMALL_DIST 1 00039 00040 #if 1 00041 # define FONT_NAME "Arial" 00042 #else 00043 # define FONT_NAME "Helvetica" 00044 #endif 00045 00046 #undef DEBUG_TEXT 00047 00048 00049 char *unescape_text_and_overbars (char *text, PangoAttrList *attrs) 00050 { 00051 char *p, *sp, *strip_text; 00052 char *overbar_start = NULL; 00053 int escape = FALSE; 00054 00055 /* The unescaped text is alwasys shorter than the original 00056 string, so just allocate the same ammount of memory. */ 00057 sp = strip_text = g_malloc (strlen (text) + 1); 00058 00059 for (p = text; p != NULL; p++) { 00060 int finish_overbar = FALSE; 00061 00062 /* If we find an escape character "\", we note it and continue looping */ 00063 if (!escape && *p == '\\') { 00064 escape = TRUE; 00065 continue; 00066 } 00067 00068 if (escape && *p == '_') { 00069 /* Overbar start or end sequence */ 00070 if (overbar_start != NULL) { 00071 finish_overbar = TRUE; 00072 } else { 00073 overbar_start = sp; 00074 } 00075 } else { 00076 /* just append the character, which may have been escaped */ 00077 *sp++ = *p; 00078 } 00079 escape = FALSE; 00080 00081 if (overbar_start != NULL && 00082 (finish_overbar || *p == '\0')) { 00083 PangoAttribute *attr; 00084 00085 attr = gschem_pango_attr_overbar_new (TRUE); 00086 attr->start_index = overbar_start - strip_text; 00087 attr->end_index = sp - strip_text; 00088 pango_attr_list_insert (attrs, attr); 00089 overbar_start = NULL; 00090 } 00091 00092 /* end of the string, stop iterating */ 00093 if (*p == '\0') 00094 break; 00095 } 00096 00097 return strip_text; 00098 } 00099 00100 00101 static void calculate_position (OBJECT *object, 00102 PangoFontMetrics *font_metrics, 00103 PangoRectangle logical_rect, 00104 PangoRectangle inked_rect, 00105 double *x, double *y) 00106 { 00107 double temp; 00108 double y_lower, y_middle, y_upper; 00109 double x_left, x_middle, x_right; 00110 double descent = pango_font_metrics_get_descent (font_metrics) / PANGO_SCALE; 00111 00112 x_left = 0; 00113 x_middle = -logical_rect.width / 2.; 00114 x_right = -logical_rect.width; 00115 00124 y_upper = -inked_rect.y; /* Top of inked extents */ 00125 y_middle = y_upper - inked_rect.height / 2.; /* Middle of inked extents */ 00126 y_lower = descent - logical_rect.height; /* Baseline of bottom line */ 00127 00128 /* Special case flips attachment point to opposite corner when 00129 * the text is rotated to 180 degrees, since the drawing code 00130 * does not rotate the text to be shown upside down. 00131 */ 00132 if (object->text->angle == 180) { 00133 temp = y_lower; y_lower = y_upper; y_upper = temp; 00134 temp = x_left; x_left = x_right; x_right = temp; 00135 } 00136 00137 switch (object->text->alignment) { 00138 default: 00139 /* Fall through to LOWER_left case */ 00140 case LOWER_LEFT: *y = y_lower; *x = x_left; break; 00141 case MIDDLE_LEFT: *y = y_middle; *x = x_left; break; 00142 case UPPER_LEFT: *y = y_upper; *x = x_left; break; 00143 case LOWER_MIDDLE: *y = y_lower; *x = x_middle; break; 00144 case MIDDLE_MIDDLE: *y = y_middle; *x = x_middle; break; 00145 case UPPER_MIDDLE: *y = y_upper; *x = x_middle; break; 00146 case LOWER_RIGHT: *y = y_lower; *x = x_right; break; 00147 case MIDDLE_RIGHT: *y = y_middle; *x = x_right; break; 00148 case UPPER_RIGHT: *y = y_upper; *x = x_right; break; 00149 } 00150 } 00151 00152 00153 static PangoFontMetrics *setup_pango_return_metrics (GSCHEM_TOPLEVEL *w_current, PangoLayout *layout, 00154 double scale_factor, OBJECT *o_current) 00155 { 00156 PangoContext *context; 00157 PangoFontDescription *desc; 00158 PangoFontMetrics *font_metrics; 00159 PangoAttrList *attrs; 00160 cairo_font_options_t *options; 00161 double font_size_pt; 00162 char *unescaped; 00163 00164 context = pango_layout_get_context (layout); 00165 00166 /* Switch off metric hinting, set medium outline hinting */ 00167 options = cairo_font_options_create (); 00168 cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF); 00169 cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_MEDIUM); 00170 pango_cairo_context_set_font_options (context, options); 00171 cairo_font_options_destroy (options); 00172 00173 pango_cairo_context_set_resolution (context, 1000. * scale_factor); 00174 font_size_pt = o_text_get_font_size_in_points (w_current->toplevel, 00175 o_current); 00176 00177 desc = pango_font_description_from_string (FONT_NAME); 00178 pango_font_description_set_size (desc, (double)PANGO_SCALE * font_size_pt); 00179 00180 pango_layout_set_font_description (layout, desc); 00181 font_metrics = pango_context_get_metrics (context, desc, NULL); 00182 pango_font_description_free (desc); 00183 00184 attrs = pango_attr_list_new (); 00185 unescaped = unescape_text_and_overbars (o_current->text->disp_string, attrs); 00186 pango_layout_set_text (layout, unescaped, -1); 00187 g_free (unescaped); 00188 pango_layout_set_attributes (layout, attrs); 00189 pango_attr_list_unref (attrs); 00190 00191 return font_metrics; 00192 } 00193 00194 00195 static void rotate_vector (double x, double y, double angle, 00196 double *rx, double *ry) 00197 { 00198 double costheta = cos (angle * M_PI / 180.); 00199 double sintheta = sin (angle * M_PI / 180.); 00200 00201 *rx = costheta * x - sintheta * y; 00202 *ry = sintheta * x + costheta * y; 00203 } 00204 00205 00206 static void expand_bounds (int *left, int *top, int *right, int *bottom, 00207 int new_x, int new_y) 00208 { 00209 *left = MIN (*left, new_x); 00210 *right = MAX (*right, new_x); 00211 *top = MIN (*top, new_y); 00212 *bottom = MAX (*bottom, new_y); 00213 } 00214 00215 00221 int o_text_get_rendered_bounds (void *user_data, OBJECT *o_current, 00222 int *min_x, int *min_y, 00223 int *max_x, int *max_y) 00224 { 00225 GSCHEM_TOPLEVEL *w_current = user_data; 00226 TOPLEVEL *toplevel = w_current->toplevel; 00227 PangoLayout *layout; 00228 cairo_t *cr; 00229 double x, y; 00230 PangoFontMetrics *font_metrics; 00231 PangoRectangle logical_rect; 00232 PangoRectangle inked_rect; 00233 int angle; 00234 double rx, ry; 00235 double tleft, ttop, tright, tbottom; 00236 int left, right, top, bottom; 00237 00238 g_return_val_if_fail (o_current != NULL, FALSE); 00239 g_return_val_if_fail (o_current->text != NULL, FALSE); 00240 00241 if (!o_is_visible (toplevel, o_current) && 00242 !toplevel->show_hidden_text) 00243 return FALSE; 00244 00245 if (o_current->text->disp_string == NULL) 00246 return FALSE; 00247 00248 cr = gdk_cairo_create (w_current->drawable); 00249 layout = pango_cairo_create_layout (cr); 00250 00251 font_metrics = setup_pango_return_metrics (w_current, layout, 1., o_current); 00252 00253 pango_layout_get_pixel_extents (layout, &inked_rect, &logical_rect); 00254 calculate_position (o_current, font_metrics, logical_rect, inked_rect, &x, &y); 00255 pango_font_metrics_unref (font_metrics); 00256 00257 tleft = x + inked_rect.x; 00258 tright = x + inked_rect.x + inked_rect.width; 00259 /* Deliberately include bounds up to the height of the logical rect, 00260 * since we draw overbars in that space. In the unlikely event that 00261 * the inked rect extends above the logical (inked_rect.y is -ve), 00262 * do take that into account. 00263 */ 00264 ttop = -y - (inked_rect.y < 0 ? inked_rect.y : 0.); 00265 tbottom = -y - inked_rect.y - inked_rect.height; 00266 00267 angle = o_current->text->angle; 00268 /* Special case turns upside down text back upright */ 00269 if (angle == 180) 00270 angle = 0; 00271 00272 rotate_vector (tleft, ttop, angle, &rx, &ry); 00273 left = right = rx; 00274 top = bottom = ry; 00275 rotate_vector (tright, ttop, angle, &rx, &ry); 00276 expand_bounds (&left, &top, &right, &bottom, rx, ry); 00277 rotate_vector (tleft, tbottom, angle, &rx, &ry); 00278 expand_bounds (&left, &top, &right, &bottom, rx, ry); 00279 rotate_vector (tright, tbottom, angle, &rx, &ry); 00280 expand_bounds (&left, &top, &right, &bottom, rx, ry); 00281 00282 *min_x = o_current->text->x + left; 00283 *max_x = o_current->text->x + right; 00284 *min_y = o_current->text->y + top; 00285 *max_y = o_current->text->y + bottom; 00286 00287 g_object_unref (layout); 00288 cairo_destroy (cr); 00289 00290 return TRUE; 00291 } 00292 00293 00294 #ifdef DEBUG_TEXT 00295 static void draw_construction_lines (GSCHEM_TOPLEVEL *w_current, 00296 double x, double y, 00297 PangoFontMetrics *font_metrics, 00298 PangoRectangle logical_rect) 00299 { 00300 double px = 1.; 00301 double dashlength; 00302 double ascent = pango_font_metrics_get_ascent (font_metrics) / PANGO_SCALE; 00303 double descent = pango_font_metrics_get_descent (font_metrics) / PANGO_SCALE; 00304 cairo_t *cr = w_current->cr; 00305 00306 /* Pick an arbitrary size constant for the construction lines */ 00307 /* Includes * 10 factor for precision */ 00308 px = SCREENabs (w_current, 4 * 10); 00309 00310 /* Threshold the drawing to be above a certain size */ 00311 if (px < 2.) 00312 return; 00313 00314 px = px / 10.; 00315 00316 /* baseline, descent, ascent, height */ 00317 cairo_set_line_width (cr, 2 * px); 00318 dashlength = 9 * px; 00319 cairo_set_dash (cr, &dashlength, 1, 0); 00320 00321 /* Underline logical text rect in green, y coord is as gschem text origin */ 00322 cairo_set_source_rgba (cr, 0, 0.6, 0, 0.5); 00323 cairo_move_to (cr, x + logical_rect.x, y + ascent); 00324 cairo_rel_line_to (cr, logical_rect.width, 0); 00325 cairo_stroke (cr); 00326 00327 /* Underline descent height in red */ 00328 cairo_set_source_rgba (cr, 1, 0, 0, 1); 00329 cairo_move_to (cr, x + logical_rect.x, y + ascent + descent); 00330 cairo_rel_line_to (cr, logical_rect.width, 0); 00331 cairo_stroke (cr); 00332 00333 /* Overbar ascent height in yellow */ 00334 cairo_set_source_rgba (cr, 1, 1, 0, 1); 00335 cairo_move_to (cr, x + logical_rect.x, y); 00336 cairo_rel_line_to (cr, logical_rect.width, 0); 00337 cairo_stroke (cr); 00338 00339 /* extents: width & height in blue */ 00340 cairo_set_source_rgba (cr, 0, 0, 0.75, 0.5); 00341 cairo_set_line_width (cr, px); 00342 dashlength = 3 * px; 00343 cairo_set_dash (cr, &dashlength, 1, 0); 00344 cairo_rectangle (cr, x + logical_rect.x, y + logical_rect.y, 00345 logical_rect.width, logical_rect.height); 00346 cairo_stroke (cr); 00347 00348 /* show layout origin point in black */ 00349 cairo_arc (cr, x, y, 3 * px, 0, 2 * M_PI); 00350 cairo_set_source_rgba (cr, 0.0, 0, 0, 0.5); 00351 cairo_fill (cr); 00352 00353 /* text's advance in blue */ 00354 cairo_set_source_rgba (cr, 0, 0, 0.75, 0.5); 00355 cairo_arc (cr, x + logical_rect.x + logical_rect.width, y + logical_rect.height - descent, 00356 3 * px, 0, 2 * M_PI); 00357 cairo_fill (cr); 00358 00359 /* reference point in red */ 00360 cairo_arc (cr, x, y + ascent, 3 * px, 0, 2 * M_PI); 00361 cairo_set_source_rgba (cr, 0.75, 0, 0, 0.5); 00362 cairo_fill (cr); 00363 } 00364 #endif 00365 00366 00372 static void o_text_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current, 00373 int dx, int dy, COLOR *color) 00374 { 00375 TOPLEVEL *toplevel = w_current->toplevel; 00376 cairo_t *cr = w_current->cr; 00377 int sx, sy; 00378 double x, y; 00379 PangoFontMetrics *font_metrics; 00380 PangoRectangle logical_rect; 00381 PangoRectangle inked_rect; 00382 00383 g_return_if_fail (o_current != NULL); 00384 g_return_if_fail (o_current->text != NULL); 00385 00386 if (!o_is_visible (toplevel, o_current) && 00387 !toplevel->show_hidden_text) 00388 return; 00389 00390 if (o_current->text->disp_string == NULL) 00391 return; 00392 00393 font_metrics = 00394 setup_pango_return_metrics (w_current, w_current->pl, 00395 toplevel->page_current->to_screen_x_constant, 00396 o_current); 00397 00398 pango_layout_get_pixel_extents (w_current->pl, &inked_rect, &logical_rect); 00399 calculate_position (o_current, font_metrics, logical_rect, inked_rect, &x, &y); 00400 00401 cairo_save (cr); 00402 00403 WORLDtoSCREEN (w_current, o_current->text->x + dx, 00404 o_current->text->y + dy, &sx, &sy); 00405 cairo_translate (cr, sx, sy); 00406 00407 /* Special case turns upside-down text back upright */ 00408 if (o_current->text->angle != 180) { 00409 cairo_rotate (cr, - M_PI * o_current->text->angle / 180.); 00410 } 00411 00412 gschem_cairo_set_source_color (w_current, color); 00413 00414 /* NB: Shift the position by 0.5px to match the hinting applied to single 00415 * pixel wide lines. This means the text will sit correctly on top of 00416 * the grid lines, and ensures consistency with other lines when the 00417 * page view is zoomed out. */ 00418 cairo_move_to (cr, x + 0.5, y + 0.5); 00419 gschem_pango_show_layout (cr, w_current->pl); 00420 00421 #ifdef DEBUG_TEXT 00422 draw_construction_lines (w_current, x, y, font_metrics, logical_rect); 00423 #endif 00424 00425 pango_font_metrics_unref (font_metrics); 00426 cairo_restore (cr); 00427 } 00428 00429 00435 #define I_OFFSET 10 00436 #define I_SMALL_DIST 20 00437 #define X_SMALL_DIST 10 00438 void o_text_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) 00439 { 00440 TOPLEVEL *toplevel = w_current->toplevel; 00441 int x, y; 00442 int color; 00443 00444 g_return_if_fail (o_current != NULL); 00445 g_return_if_fail (o_current->type == OBJ_TEXT); 00446 g_return_if_fail (o_current->text != NULL); 00447 00448 if (!o_is_visible (toplevel, o_current) && !toplevel->show_hidden_text) { 00449 return; 00450 } 00451 00452 if (!w_current->fast_mousepan || !w_current->doing_pan) { 00453 00454 o_text_draw_lowlevel (w_current, o_current, 0, 0, 00455 o_drawing_color (w_current, o_current)); 00456 00457 /* Indicate on the schematic that the text is invisible by */ 00458 /* drawing a little I on the screen at the origin */ 00459 if (!o_is_visible (toplevel, o_current) && toplevel->show_hidden_text) { 00460 if (toplevel->override_color != -1 ) 00461 color = toplevel->override_color; 00462 else 00463 color = LOCK_COLOR; 00464 00465 x = o_current->text->x + I_OFFSET; 00466 y = o_current->text->y - I_OFFSET; 00467 00468 /* Top part of the I */ 00469 gschem_cairo_line (w_current, END_NONE, 1, x, y, x + I_SMALL_DIST, y); 00470 /* Middle part of the I */ 00471 gschem_cairo_line (w_current, END_NONE, 1, x + I_SMALL_DIST / 2, y, 00472 x + I_SMALL_DIST / 2, y - I_SMALL_DIST); 00473 /* Bottom part of the I */ 00474 gschem_cairo_line (w_current, END_NONE, 1, x, y - I_SMALL_DIST, 00475 x + I_SMALL_DIST, y - I_SMALL_DIST); 00476 00477 gschem_cairo_set_source_color (w_current, x_color_lookup (color)); 00478 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 1, -1, -1); 00479 } 00480 } else { 00481 /* draw a box in it's place */ 00482 gschem_cairo_box (w_current, 0, 00483 o_current->w_left, o_current->w_bottom, 00484 o_current->w_right, o_current->w_top); 00485 00486 gschem_cairo_set_source_color (w_current, 00487 o_drawing_color (w_current, o_current)); 00488 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1); 00489 00490 return; 00491 } 00492 00493 /* return if text origin marker displaying is disabled */ 00494 if (w_current->text_origin_marker == FALSE) { 00495 return; 00496 } 00497 00498 /* Switch of mark drawing for non-selected text, and at small sizes */ 00499 if (!o_current->selected || 00500 SCREENabs (w_current, X_SMALL_DIST) < MINIMUM_MARK_SMALL_DIST) 00501 return; 00502 00503 if (toplevel->override_color != -1 ) 00504 color = toplevel->override_color; 00505 else 00506 color = LOCK_COLOR; 00507 00508 /* reference point */ 00509 x = o_current->text->x; 00510 y = o_current->text->y; 00511 gschem_cairo_line (w_current, END_NONE, 1, 00512 x - X_SMALL_DIST, y + X_SMALL_DIST, 00513 x + X_SMALL_DIST, y - X_SMALL_DIST); 00514 gschem_cairo_line (w_current, END_NONE, 1, 00515 x + X_SMALL_DIST, y + X_SMALL_DIST, 00516 x - X_SMALL_DIST, y - X_SMALL_DIST); 00517 gschem_cairo_set_source_color (w_current, x_color_lookup (color)); 00518 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 1, -1, -1); 00519 } 00520 #undef OFFSET 00521 #undef SMALL_DIST 00522 00523 00529 void o_text_draw_place (GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current) 00530 { 00531 TOPLEVEL *toplevel = w_current->toplevel; 00532 int factor; 00533 00534 if (!o_is_visible (toplevel, o_current) && !toplevel->show_hidden_text) { 00535 return; 00536 } 00537 00538 /* always display text which is 12 or larger */ 00539 factor = (int) toplevel->page_current->to_world_x_constant; 00540 if ((factor < w_current->text_display_zoomfactor) || 00541 o_current->text->size >= 12 || 00542 w_current->text_feedback == ALWAYS) { 00543 00544 o_text_draw_lowlevel (w_current, o_current, dx, dy, 00545 x_color_lookup_dark (o_current->color)); 00546 00547 } else { 00548 /* text is too small so draw a box in it's place */ 00549 00550 gschem_cairo_box (w_current, 0, 00551 o_current->w_left + dx, o_current->w_bottom + dy, 00552 o_current->w_right + dx, o_current->w_top + dy); 00553 00554 gschem_cairo_set_source_color (w_current, 00555 x_color_lookup_dark (o_current->color)); 00556 gschem_cairo_stroke (w_current, TYPE_SOLID, END_NONE, 0, -1, -1); 00557 } 00558 } 00559 00560 00566 void o_text_prepare_place(GSCHEM_TOPLEVEL *w_current, char *text) 00567 { 00568 TOPLEVEL *toplevel = w_current->toplevel; 00569 00570 /* Insert the new object into the buffer at world coordinates (0,0). 00571 * It will be translated to the mouse coordinates during placement. */ 00572 00573 w_current->first_wx = 0; 00574 w_current->first_wy = 0; 00575 00576 w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE; 00577 00578 /* remove the old place list if it exists */ 00579 s_delete_object_glist(toplevel, toplevel->page_current->place_list); 00580 toplevel->page_current->place_list = NULL; 00581 00582 /* here you need to add OBJ_TEXT when it's done */ 00583 toplevel->page_current->place_list = 00584 g_list_append(toplevel->page_current->place_list, 00585 o_text_new (toplevel, OBJ_TEXT, TEXT_COLOR, 00586 0, 0, LOWER_LEFT, 0, /* zero is angle */ 00587 text, 00588 w_current->text_size, 00589 /* has to be visible so you can place it */ 00590 /* visibility is set when you create the object */ 00591 VISIBLE, SHOW_NAME_VALUE)); 00592 00593 w_current->inside_action = 1; 00594 i_set_state (w_current, ENDTEXT); 00595 } 00596 00597 00603 void o_text_edit(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current) 00604 { 00605 /* you need to check to make sure only one object is selected */ 00606 /* no actually this is okay... not here in o_edit */ 00607 text_edit_dialog(w_current, 00608 o_text_get_string (w_current->toplevel, o_current), 00609 o_current->text->size, o_current->text->alignment); 00610 } 00611 00617 void o_text_edit_end(GSCHEM_TOPLEVEL *w_current, char *string, int len, int text_size, 00618 int text_alignment) 00619 { 00620 TOPLEVEL *toplevel = w_current->toplevel; 00621 OBJECT *object; 00622 GList *s_current; 00623 int numselect; 00624 00625 /* skip over head */ 00626 s_current = geda_list_get_glist( toplevel->page_current->selection_list ); 00627 numselect = g_list_length( geda_list_get_glist( toplevel->page_current->selection_list )); 00628 00629 while(s_current != NULL) { 00630 object = (OBJECT *) s_current->data; 00631 00632 if (object) { 00633 if (object->type == OBJ_TEXT) { 00634 00635 object->text->size = text_size; 00636 object->text->alignment = text_alignment; 00637 00638 /* probably the text object should be extended to carry a color */ 00639 /* and we should pass it here with a function parameter (?) */ 00640 object->color = w_current->edit_color; 00641 00642 /* only change text string if there is only ONE text object selected */ 00643 if (numselect == 1 && string) { 00644 o_text_set_string (w_current->toplevel, object, string); 00645 /* handle slot= attribute, it's a special case */ 00646 if (object->attached_to != NULL && 00647 g_ascii_strncasecmp (string, "slot=", 5) == 0) { 00648 o_slot_end (w_current, object->attached_to, string); 00649 } 00650 } 00651 o_text_recreate(toplevel, object); 00652 } 00653 } 00654 00655 s_current = g_list_next(s_current); 00656 } 00657 00658 toplevel->page_current->CHANGED = 1; 00659 o_undo_savestate(w_current, UNDO_ALL); 00660 } 00661 00670 void o_text_change(GSCHEM_TOPLEVEL *w_current, OBJECT *object, char *string, 00671 int visibility, int show) 00672 { 00673 TOPLEVEL *toplevel = w_current->toplevel; 00674 if (object == NULL) { 00675 return; 00676 } 00677 00678 if (object->type != OBJ_TEXT) { 00679 return; 00680 } 00681 00682 o_text_set_string (toplevel, object, string); 00683 00684 o_set_visibility (toplevel, object, visibility); 00685 object->show_name_value = show; 00686 o_text_recreate(toplevel, object); 00687 00688 /* handle slot= attribute, it's a special case */ 00689 if (object->attached_to != NULL && 00690 g_ascii_strncasecmp (string, "slot=", 5) == 0) { 00691 o_slot_end (w_current, object->attached_to, string); 00692 } 00693 00694 toplevel->page_current->CHANGED = 1; 00695 }