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
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 */
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
));
94 /*! \todo Finish function documentation!!!
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
);
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 */
127 g_list_append(page
->place_list
,
128 o_text_new (toplevel
, color
,
129 0, 0, align
, rotate
, /* zero is angle */
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!!!
143 * \par Function Description
146 * The object passed in should be the REAL object, NOT any copy in any
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
) {
167 if (object
->type
!= OBJ_TEXT
) {
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
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')
205 if (o_attrib_string_get_name_value (object
->text
->string
, &name
, &value
)) {
206 buf
= g_strdup_printf ("\\_%s\\_", value
);
210 buf
= g_strdup_printf ("\\_%s\\_", object
->text
->string
);
213 ptr
= buf
+ strlen (buf
) - 4;
214 if (strncmp (ptr
, "\\_\\_", 4) == 0)
217 if (strncmp (ptr
, "\\_\\_", 4) == 0)
221 new_string
= g_strdup (ptr
);
223 new_string
= g_strdup_printf ("%s=%s", name
, ptr
);
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
);