Bump gEDA version
[geda-gaf.git] / gschem / src / o_text.c
blob4a37d5f6f91205c271403280c926fe0b71b4bfb5
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 *min_x = lrint (fmin (l, r));
85 *min_y = lrint (fmin (t, b));
86 *max_x = lrint (fmax (l, r));
87 *max_y = lrint (fmax (t, b));
89 return result;
92 /*! \todo Finish function documentation!!!
93 * \brief
94 * \par Function Description
97 void o_text_prepare_place(GschemToplevel *w_current, char *text, int color, int align, int rotate, int size)
99 GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
100 g_return_if_fail (page_view != NULL);
102 PAGE *page = gschem_page_view_get_page (page_view);
103 if (page == NULL) {
104 return;
107 TOPLEVEL *toplevel = page->toplevel;
108 g_return_if_fail (toplevel != NULL);
111 /* Insert the new object into the buffer at world coordinates (0,0).
112 * It will be translated to the mouse coordinates during placement. */
114 w_current->first_wx = 0;
115 w_current->first_wy = 0;
117 w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE;
119 /* remove the old place list if it exists */
120 s_delete_object_glist(toplevel, page->place_list);
121 page->place_list = NULL;
123 /* here you need to add OBJ_TEXT when it's done */
124 page->place_list =
125 g_list_append(page->place_list,
126 o_text_new (toplevel, color,
127 0, 0, align, rotate, /* zero is angle */
128 text,
129 size,
130 /* has to be visible so you can place it */
131 /* visibility is set when you create the object */
132 VISIBLE, SHOW_NAME_VALUE));
134 i_action_start (w_current);
135 i_set_state (w_current, TEXTMODE);
139 /*! \todo Finish function documentation!!!
140 * \brief
141 * \par Function Description
143 * \note
144 * The object passed in should be the REAL object, NOT any copy in any
145 * selection list
147 void o_text_change(GschemToplevel *w_current, OBJECT *object, char *string,
148 int visibility, int show)
150 g_return_if_fail (w_current != NULL);
152 GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current);
153 g_return_if_fail (page_view != NULL);
155 PAGE *page = gschem_page_view_get_page (page_view);
156 TOPLEVEL *toplevel = page->toplevel;
158 g_return_if_fail (toplevel != NULL);
159 g_return_if_fail (page != NULL);
161 if (object == NULL) {
162 return;
165 if (object->type != OBJ_TEXT) {
166 return;
169 o_text_set_string (toplevel, object, string);
171 o_set_visibility (toplevel, object, visibility);
172 object->show_name_value = show;
173 o_text_recreate(toplevel, object);
175 /* handle slot= attribute, it's a special case */
176 if (object->attached_to != NULL &&
177 g_ascii_strncasecmp (string, "slot=", 5) == 0) {
178 o_slot_end (w_current, object->attached_to, string);
183 /*! \brief Toggle a text object's overbar.
185 * Adds an overbar marker (backslash-underline) to the begin and the
186 * end of the text object's contents if there's not already an overbar
187 * marker; otherwise, removes the existing marker. Begin and end are
188 * treated independently, so the parts of the text with and without
189 * overbar are complemented.
191 * \returns whether the object has been changed
193 gboolean
194 o_text_toggle_overbar (GschemToplevel *w_current, OBJECT *object)
196 TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current);
197 gchar *name, *value, *buf, *ptr, *new_string;
199 if (object->type != OBJ_TEXT || object->text->string == NULL
200 || object->text->string[0] == '\0')
201 return FALSE;
203 if (o_attrib_string_get_name_value (object->text->string, &name, &value)) {
204 buf = g_strdup_printf ("\\_%s\\_", value);
205 g_free (value);
206 } else {
207 name = NULL;
208 buf = g_strdup_printf ("\\_%s\\_", object->text->string);
211 ptr = buf + strlen (buf) - 4;
212 if (strncmp (ptr, "\\_\\_", 4) == 0)
213 *ptr = '\0';
214 ptr = buf;
215 if (strncmp (ptr, "\\_\\_", 4) == 0)
216 ptr += 4;
218 if (name == NULL)
219 new_string = g_strdup (ptr);
220 else {
221 new_string = g_strdup_printf ("%s=%s", name, ptr);
222 g_free (name);
224 g_free (buf);
226 o_text_set_string (toplevel, object, new_string);
227 /* o_text_recreate is called by o_text_set_string */
229 /* handle slot= attribute, it's a special case */
230 if (object->attached_to != NULL &&
231 g_ascii_strncasecmp (new_string, "slot=", 5) == 0)
232 o_slot_end (w_current, object->attached_to, new_string);
234 g_free (new_string);
235 return TRUE;