1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2019 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
34 /*! \todo Finish function documentation!!!
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
)
44 EdaRenderer
*renderer
;
46 cairo_matrix_t render_mtx
;
47 int result
, render_flags
= 0;
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
),
68 "render-flags", render_flags
,
71 /* We need to transform the cairo context to approximate world
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
);
80 eda_renderer_destroy (renderer
);
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
));
92 /*! \todo Finish function documentation!!!
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
);
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 */
125 g_list_append(page
->place_list
,
126 o_text_new (toplevel
, color
,
127 0, 0, align
, rotate
, /* zero is angle */
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!!!
141 * \par Function Description
144 * The object passed in should be the REAL object, NOT any copy in any
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
) {
165 if (object
->type
!= OBJ_TEXT
) {
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
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')
203 if (o_attrib_string_get_name_value (object
->text
->string
, &name
, &value
)) {
204 buf
= g_strdup_printf ("\\_%s\\_", value
);
208 buf
= g_strdup_printf ("\\_%s\\_", object
->text
->string
);
211 ptr
= buf
+ strlen (buf
) - 4;
212 if (strncmp (ptr
, "\\_\\_", 4) == 0)
215 if (strncmp (ptr
, "\\_\\_", 4) == 0)
219 new_string
= g_strdup (ptr
);
221 new_string
= g_strdup_printf ("%s=%s", name
, ptr
);
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
);