gschem

o_text.c

Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines