missing NULL terminator in set_config_x
[geda-gaf.git] / gschem / src / o_text.c
blobca5a8db4d4fb58aa355467f9e04feb24885eea23
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <math.h>
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
32 #include "gschem.h"
34 /*! \todo Finish function documentation!!!
35 * \brief
36 * \par Function Description
39 int o_text_get_rendered_bounds (void *user_data, OBJECT *o_current,
40 int *min_x, int *min_y,
41 int *max_x, int *max_y)
43 TOPLEVEL *toplevel;
44 EdaRenderer *renderer;
45 cairo_t *cr;
46 cairo_matrix_t render_mtx;
47 int result, render_flags = 0;
48 double t, l, r, b;
49 GschemToplevel *w_current = (GschemToplevel *) user_data;
50 g_return_val_if_fail ((w_current != NULL), FALSE);
52 GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
53 g_return_val_if_fail ((page_view != NULL), FALSE);
55 toplevel = gschem_toplevel_get_toplevel (w_current);
56 g_return_val_if_fail ((toplevel != NULL), FALSE);
58 cr = gdk_cairo_create (gtk_widget_get_window (GTK_WIDGET(page_view)));
60 /* Set up renderer based on configuration in w_current. Note that we
61 * *don't* enable hinting, because if its enabled the calculated
62 * bounds are zoom-level-dependent. */
63 if (toplevel->show_hidden_text)
64 render_flags |= EDA_RENDERER_FLAG_TEXT_HIDDEN;
65 renderer = g_object_ref (w_current->renderer);
66 g_object_set (G_OBJECT (renderer),
67 "cairo-context", cr,
68 "render-flags", render_flags,
69 NULL);
71 /* We need to transform the cairo context to approximate world
72 * coordinates. */
73 cairo_matrix_init (&render_mtx, 1, 0, 0, -1, -1, 1);
74 cairo_set_matrix (cr, &render_mtx);
76 /* Use the renderer to calculate text bounds */
77 result = eda_renderer_get_user_bounds (renderer, o_current, &l, &t, &r, &b);
79 /* Clean up */
80 eda_renderer_destroy (renderer);
81 cairo_destroy (cr);
83 /* Round bounds to nearest integer */
84 if (result) {
85 *min_x = lrint (fmin (l, r));
86 *min_y = lrint (fmin (t, b));
87 *max_x = lrint (fmax (l, r));
88 *max_y = lrint (fmax (t, b));
91 return result;
94 /*! \todo Finish function documentation!!!
95 * \brief
96 * \par Function Description
99 void o_text_prepare_place(GschemToplevel *w_current, char *text, int color, int align, int rotate, int size)
101 GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
102 g_return_if_fail (page_view != NULL);
104 PAGE *page = gschem_page_view_get_page (page_view);
105 if (page == NULL) {
106 return;
109 TOPLEVEL *toplevel = page->toplevel;
110 g_return_if_fail (toplevel != NULL);
113 /* Insert the new object into the buffer at world coordinates (0,0).
114 * It will be translated to the mouse coordinates during placement. */
116 w_current->first_wx = 0;
117 w_current->first_wy = 0;
119 w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
121 /* remove the old place list if it exists */
122 s_delete_object_glist(toplevel, page->place_list);
123 page->place_list = NULL;
125 /* here you need to add OBJ_TEXT when it's done */
126 page->place_list =
127 g_list_append(page->place_list,
128 o_text_new (toplevel, color,
129 0, 0, align, rotate, /* zero is angle */
130 text,
131 size,
132 /* has to be visible so you can place it */
133 /* visibility is set when you create the object */
134 VISIBLE, SHOW_NAME_VALUE));
136 i_action_start (w_current);
137 i_set_state (w_current, TEXTMODE);
141 /*! \todo Finish function documentation!!!
142 * \brief
143 * \par Function Description
145 * \note
146 * The object passed in should be the REAL object, NOT any copy in any
147 * selection list
149 void o_text_change(GschemToplevel *w_current, OBJECT *object, char *string,
150 int visibility, int show)
152 g_return_if_fail (w_current != NULL);
154 GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
155 g_return_if_fail (page_view != NULL);
157 PAGE *page = gschem_page_view_get_page (page_view);
158 TOPLEVEL *toplevel = page->toplevel;
160 g_return_if_fail (toplevel != NULL);
161 g_return_if_fail (page != NULL);
163 if (object == NULL) {
164 return;
167 if (object->type != OBJ_TEXT) {
168 return;
171 o_text_set_string (toplevel, object, string);
173 o_set_visibility (toplevel, object, visibility);
174 object->show_name_value = show;
175 o_text_recreate(toplevel, object);
177 /* handle slot= attribute, it's a special case */
178 if (object->attached_to != NULL &&
179 g_ascii_strncasecmp (string, "slot=", 5) == 0) {
180 o_slot_end (w_current, object->attached_to, string);
185 /*! \brief Toggle a text object's overbar.
187 * Adds an overbar marker (backslash-underline) to the begin and the
188 * end of the text object's contents if there's not already an overbar
189 * marker; otherwise, removes the existing marker. Begin and end are
190 * treated independently, so the parts of the text with and without
191 * overbar are complemented.
193 * \returns whether the object has been changed
195 gboolean
196 o_text_toggle_overbar (GschemToplevel *w_current, OBJECT *object)
198 TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
199 gchar *name, *value, *buf, *ptr, *new_string;
201 if (object->type != OBJ_TEXT || object->text->string == NULL
202 || object->text->string[0] == '\0')
203 return FALSE;
205 if (o_attrib_string_get_name_value (object->text->string, &name, &value)) {
206 buf = g_strdup_printf ("\\_%s\\_", value);
207 g_free (value);
208 } else {
209 name = NULL;
210 buf = g_strdup_printf ("\\_%s\\_", object->text->string);
213 ptr = buf + strlen (buf) - 4;
214 if (strncmp (ptr, "\\_\\_", 4) == 0)
215 *ptr = '\0';
216 ptr = buf;
217 if (strncmp (ptr, "\\_\\_", 4) == 0)
218 ptr += 4;
220 if (name == NULL)
221 new_string = g_strdup (ptr);
222 else {
223 new_string = g_strdup_printf ("%s=%s", name, ptr);
224 g_free (name);
226 g_free (buf);
228 o_text_set_string (toplevel, object, new_string);
229 /* o_text_recreate is called by o_text_set_string */
231 /* handle slot= attribute, it's a special case */
232 if (object->attached_to != NULL &&
233 g_ascii_strncasecmp (new_string, "slot=", 5) == 0)
234 o_slot_end (w_current, object->attached_to, new_string);
236 g_free (new_string);
237 return TRUE;