Code

Node tool: special case node duplication for endnodes - select new endnode
[inkscape.git] / src / libcroco / cr-num.c
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
3 /*
4  * This file is part of The Croco Library
5  *
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2.1 of the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
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.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * Author: Dodji Seketeli
22  * See COPYRIGHTS file for copyrights information.
23  */
25 /**
26  *@file
27  *The definition
28  *of the #CRNum class.
29  */
31 #include "cr-num.h"
32 #include "string.h"
34 /**
35  *The default constructor of
36  *#CRNum.
37  *@return the newly built instance of
38  *#CRNum.
39  */
40 CRNum *
41 cr_num_new (void)
42 {
43         CRNum *result = (CRNum *)g_try_malloc (sizeof (CRNum));
45         if (result == NULL) {
46                 cr_utils_trace_info ("Out of memory");
47                 return NULL;
48         }
50         memset (result, 0, sizeof (CRNum));
52         return result;
53 }
55 /**
56  *A constructor of #CRNum.
57  *@param a_is_natural indicates whether the intance of #CRNum is 
58  *a natural number or not.
59  *@param a_integer_part the integer part of the instance 
60  *of #CRNum
61  *@param a_decimal_part in case the instance of #CRNum
62  *natural number (but a decimal one) this parameter
63  *is the decimal part of the instance of #CRNum.
64  *@return the newly built instance of #CRNum or
65  *NULL if an error arises.
66  */
67 CRNum *
68 cr_num_new_with_val (gdouble a_val, enum CRNumType a_type)
69 {
70         CRNum *result = NULL;
72         result = cr_num_new ();
74         g_return_val_if_fail (result, NULL);
76         result->val = a_val;
77         result->type = a_type;
79         return result;
80 }
82 /**
83  *Returns the string representation of the
84  *current instance of #CRNum.
85  *@param a_this the current instance of #CRNum.
86  *@return the newly built string representation
87  *of the current instance of #CRNum. The returned
88  *string is NULL terminated. The caller *must*
89  *free the returned string.
90  */
91 guchar *
92 cr_num_to_string (CRNum * a_this)
93 {
94         gdouble test_val = 0.0;
96         guchar *tmp_char1 = NULL,
97                 *tmp_char2 = NULL,
98                 *result = NULL;
100         g_return_val_if_fail (a_this, NULL);
102         test_val = a_this->val - (glong) a_this->val;
104         if (!test_val) {
105                 tmp_char1 = (guchar *)g_strdup_printf ("%ld", (glong) a_this->val);
106         } else {
107                 /* We can't use g_ascii_dtostr, because that sometimes uses
108                    e notation (which wouldn't be a valid number in CSS). */
109                 size_t const buflen = 35;  /* fairly arbitrary. */
110                 tmp_char1 = (guchar *)g_malloc (buflen);
111                 g_ascii_formatd ((gchar *)tmp_char1, buflen, "%.17f", a_this->val);
112         }
114         g_return_val_if_fail (tmp_char1, NULL);
116         switch (a_this->type) {
117         case NUM_LENGTH_EM:
118                 tmp_char2 = (guchar *) "em";
119                 break;
121         case NUM_LENGTH_EX:
122                 tmp_char2 = (guchar *) "ex";
123                 break;
125         case NUM_LENGTH_PX:
126                 tmp_char2 = (guchar *) "px";
127                 break;
129         case NUM_LENGTH_IN:
130                 tmp_char2 = (guchar *) "in";
131                 break;
133         case NUM_LENGTH_CM:
134                 tmp_char2 = (guchar *) "cm";
135                 break;
137         case NUM_LENGTH_MM:
138                 tmp_char2 = (guchar *) "mm";
139                 break;
141         case NUM_LENGTH_PT:
142                 tmp_char2 = (guchar *) "pt";
143                 break;
145         case NUM_LENGTH_PC:
146                 tmp_char2 = (guchar *) "pc";
147                 break;
149         case NUM_ANGLE_DEG:
150                 tmp_char2 = (guchar *) "deg";
151                 break;
153         case NUM_ANGLE_RAD:
154                 tmp_char2 = (guchar *) "rad";
155                 break;
157         case NUM_ANGLE_GRAD:
158                 tmp_char2 = (guchar *) "grad";
159                 break;
161         case NUM_TIME_MS:
162                 tmp_char2 = (guchar *) "ms";
163                 break;
165         case NUM_TIME_S:
166                 tmp_char2 = (guchar *) "s";
167                 break;
169         case NUM_FREQ_HZ:
170                 tmp_char2 = (guchar *) "Hz";
171                 break;
173         case NUM_FREQ_KHZ:
174                 tmp_char2 = (guchar *) "KHz";
175                 break;
177         case NUM_PERCENTAGE:
178                 tmp_char2 = (guchar *) "%";
179                 break;
180         case NUM_INHERIT:
181                 tmp_char2 = (guchar *) "inherit";
182                 break ;
183         case NUM_AUTO:
184                 tmp_char2 = (guchar *) "auto";
185                 break ;
186         case NUM_GENERIC:
187                 tmp_char2 = NULL ;
188                 break ;
189         default:
190                 tmp_char2 = (guchar *) "unknown";
191                 break;
192         }
194         if (tmp_char2) {
195                 result = (guchar *)g_strconcat (
196                                     (gchar *)tmp_char1, (gchar *)tmp_char2, NULL);
197                 g_free (tmp_char1);
198         } else {
199                 result = tmp_char1;
200         }
202         return result;
205 /**
206  *Copies an instance of #CRNum.
207  *@param a_src the instance of #CRNum to copy.
208  *Must be non NULL.
209  *@param a_dst the destination of the copy.
210  *Must be non NULL
211  *@return CR_OK upon successful completion, an
212  *error code otherwise.
213  */
214 enum CRStatus
215 cr_num_copy (CRNum * a_dest, CRNum * a_src)
217         g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
219         memcpy (a_dest, a_src, sizeof (CRNum));
221         return CR_OK;
224 /**
225  *Duplicates an instance of #CRNum
226  *@param a_this the instance of #CRNum to duplicate.
227  *@return the newly created (duplicated) instance of #CRNum.
228  *Must be freed by cr_num_destroy().
229  */
230 CRNum *
231 cr_num_dup (CRNum * a_this)
233         CRNum *result = NULL;
234         enum CRStatus status = CR_OK;
236         g_return_val_if_fail (a_this, NULL);
238         result = cr_num_new ();
239         g_return_val_if_fail (result, NULL);
241         status = cr_num_copy (result, a_this);
242         g_return_val_if_fail (status == CR_OK, NULL);
244         return result;
247 /**
248  *Sets an instance of #CRNum.
249  *@param a_this the current instance of #CRNum to be set.
250  *@param a_val the new numerical value to be hold by the current
251  *instance of #CRNum
252  *@param a_type the new type of #CRNum.
253  */
254 enum CRStatus
255 cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type)
257         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
259         a_this->val = a_val;
260         a_this->type = a_type;
262         return CR_OK;
265 /**
266  *Tests if the current instance of #CRNum is a fixed
267  *length value or not. Typically a fixed length value
268  *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC.
269  *See the definition of #CRNumType to see what we mean.
270  *@return TRUE if the instance of #CRNum is a fixed length number,
271  *FALSE otherwise.
272  */
273 gboolean
274 cr_num_is_fixed_length (CRNum * a_this)
276         gboolean result = FALSE;
278         g_return_val_if_fail (a_this, FALSE);
280         if (a_this->type >= NUM_LENGTH_EM 
281             && a_this->type <= NUM_LENGTH_PC) {
282                 result = TRUE ;
283         }
284         return result ;
287 /**
288  *The destructor of #CRNum.
289  *@param a_this the this pointer of
290  *the current instance of #CRNum.
291  */
292 void
293 cr_num_destroy (CRNum * a_this)
295         g_return_if_fail (a_this);
297         g_free (a_this);