Libcroco
cr-num.c
Go to the documentation of this file.
1 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
2 
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  */
24 
25 /**
26  *@CRNum:
27  *
28  *The definition
29  *of the #CRNum class.
30  */
31 
32 #include "cr-num.h"
33 #include "string.h"
34 
35 /**
36  * cr_num_new:
37  *
38  *#CRNum.
39  *
40  *Returns the newly built instance of
41  *#CRNum.
42  */
43 CRNum *
44 cr_num_new (void)
45 {
46  CRNum *result = NULL;
47 
48  result = g_try_malloc (sizeof (CRNum));
49 
50  if (result == NULL) {
51  cr_utils_trace_info ("Out of memory");
52  return NULL;
53  }
54 
55  memset (result, 0, sizeof (CRNum));
56 
57  return result;
58 }
59 
60 /**
61  * cr_num_new_with_val:
62  * @a_val: the numerical value of the number.
63  * @a_type: the type of number.
64  *
65  * A constructor of #CRNum.
66  *
67  * Returns the newly built instance of #CRNum or
68  * NULL if an error arises.
69  */
70 CRNum *
71 cr_num_new_with_val (gdouble a_val, enum CRNumType a_type)
72 {
73  CRNum *result = NULL;
74 
75  result = cr_num_new ();
76 
77  g_return_val_if_fail (result, NULL);
78 
79  result->val = a_val;
80  result->type = a_type;
81 
82  return result;
83 }
84 
85 /**
86  * cr_num_to_string:
87  *@a_this: the current instance of #CRNum.
88  *
89  *Returns the newly built string representation
90  *of the current instance of #CRNum. The returned
91  *string is NULL terminated. The caller *must*
92  *free the returned string.
93  */
94 guchar *
95 cr_num_to_string (CRNum const * a_this)
96 {
97  gdouble test_val = 0.0;
98 
99  guchar *tmp_char1 = NULL,
100  *tmp_char2 = NULL,
101  *result = NULL;
102 
103  g_return_val_if_fail (a_this, NULL);
104 
105  test_val = a_this->val - (glong) a_this->val;
106 
107  if (!test_val) {
108  tmp_char1 = (guchar *) g_strdup_printf ("%ld", (glong) a_this->val);
109  } else {
110  tmp_char1 = (guchar *) g_new0 (char, G_ASCII_DTOSTR_BUF_SIZE + 1);
111  if (tmp_char1 != NULL)
112  g_ascii_dtostr ((gchar *) tmp_char1, G_ASCII_DTOSTR_BUF_SIZE, a_this->val);
113  }
114 
115  g_return_val_if_fail (tmp_char1, NULL);
116 
117  switch (a_this->type) {
118  case NUM_LENGTH_EM:
119  tmp_char2 = (guchar *) "em";
120  break;
121 
122  case NUM_LENGTH_EX:
123  tmp_char2 = (guchar *) "ex";
124  break;
125 
126  case NUM_LENGTH_PX:
127  tmp_char2 = (guchar *) "px";
128  break;
129 
130  case NUM_LENGTH_IN:
131  tmp_char2 = (guchar *) "in";
132  break;
133 
134  case NUM_LENGTH_CM:
135  tmp_char2 = (guchar *) "cm";
136  break;
137 
138  case NUM_LENGTH_MM:
139  tmp_char2 = (guchar *) "mm";
140  break;
141 
142  case NUM_LENGTH_PT:
143  tmp_char2 = (guchar *) "pt";
144  break;
145 
146  case NUM_LENGTH_PC:
147  tmp_char2 = (guchar *) "pc";
148  break;
149 
150  case NUM_ANGLE_DEG:
151  tmp_char2 = (guchar *) "deg";
152  break;
153 
154  case NUM_ANGLE_RAD:
155  tmp_char2 = (guchar *) "rad";
156  break;
157 
158  case NUM_ANGLE_GRAD:
159  tmp_char2 = (guchar *) "grad";
160  break;
161 
162  case NUM_TIME_MS:
163  tmp_char2 = (guchar *) "ms";
164  break;
165 
166  case NUM_TIME_S:
167  tmp_char2 = (guchar *) "s";
168  break;
169 
170  case NUM_FREQ_HZ:
171  tmp_char2 = (guchar *) "Hz";
172  break;
173 
174  case NUM_FREQ_KHZ:
175  tmp_char2 = (guchar *) "KHz";
176  break;
177 
178  case NUM_PERCENTAGE:
179  tmp_char2 = (guchar *) "%";
180  break;
181  case NUM_INHERIT:
182  tmp_char2 = (guchar *) "inherit";
183  break ;
184  case NUM_AUTO:
185  tmp_char2 = (guchar *) "auto";
186  break ;
187  case NUM_GENERIC:
188  tmp_char2 = NULL ;
189  break ;
190  default:
191  tmp_char2 = (guchar *) "unknown";
192  break;
193  }
194 
195  if (tmp_char2) {
196  result = (guchar *) g_strconcat ((gchar *) tmp_char1, tmp_char2, NULL);
197  g_free (tmp_char1);
198  } else {
199  result = tmp_char1;
200  }
201 
202  return result;
203 }
204 
205 /**
206  * cr_num_copy:
207  *@a_src: the instance of #CRNum to copy.
208  *Must be non NULL.
209  *@a_dest: the destination of the copy.
210  *Must be non NULL
211  *
212  *Copies an instance of #CRNum.
213  *
214  *Returns CR_OK upon successful completion, an
215  *error code otherwise.
216  */
217 enum CRStatus
218 cr_num_copy (CRNum * a_dest, CRNum const * a_src)
219 {
220  g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
221 
222  memcpy (a_dest, a_src, sizeof (CRNum));
223 
224  return CR_OK;
225 }
226 
227 /**
228  * cr_num_dup:
229  *@a_this: the instance of #CRNum to duplicate.
230  *
231  *Duplicates an instance of #CRNum
232  *
233  *Returns the newly created (duplicated) instance of #CRNum.
234  *Must be freed by cr_num_destroy().
235  */
236 CRNum *
237 cr_num_dup (CRNum const * a_this)
238 {
239  CRNum *result = NULL;
240  enum CRStatus status = CR_OK;
241 
242  g_return_val_if_fail (a_this, NULL);
243 
244  result = cr_num_new ();
245  g_return_val_if_fail (result, NULL);
246 
247  status = cr_num_copy (result, a_this);
248  g_return_val_if_fail (status == CR_OK, NULL);
249 
250  return result;
251 }
252 
253 /**
254  * cr_num_set:
255  *Sets an instance of #CRNum.
256  *@a_this: the current instance of #CRNum to be set.
257  *@a_val: the new numerical value to be hold by the current
258  *instance of #CRNum
259  *@a_type: the new type of #CRNum.
260  *
261  * Returns CR_OK upon succesful completion, an error code otherwise.
262  */
263 enum CRStatus
264 cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type)
265 {
266  g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
267 
268  a_this->val = a_val;
269  a_this->type = a_type;
270 
271  return CR_OK;
272 }
273 
274 /**
275  * cr_num_is_fixed_length:
276  * @a_this: the current instance of #CRNum .
277  *
278  *Tests if the current instance of #CRNum is a fixed
279  *length value or not. Typically a fixed length value
280  *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC.
281  *See the definition of #CRNumType to see what we mean.
282  *
283  *Returns TRUE if the instance of #CRNum is a fixed length number,
284  *FALSE otherwise.
285  */
286 gboolean
288 {
289  gboolean result = FALSE;
290 
291  g_return_val_if_fail (a_this, FALSE);
292 
293  if (a_this->type >= NUM_LENGTH_EM
294  && a_this->type <= NUM_LENGTH_PC) {
295  result = TRUE ;
296  }
297  return result ;
298 }
299 
300 /**
301  * cr_num_destroy:
302  *@a_this: the this pointer of
303  *the current instance of #CRNum.
304  *
305  *The destructor of #CRNum.
306  */
307 void
309 {
310  g_return_if_fail (a_this);
311 
312  g_free (a_this);
313 }
NUM_LENGTH_IN
@ NUM_LENGTH_IN
Definition: cr-num.h:61
NUM_LENGTH_MM
@ NUM_LENGTH_MM
Definition: cr-num.h:63
NUM_FREQ_KHZ
@ NUM_FREQ_KHZ
Definition: cr-num.h:72
cr_num_set
enum CRStatus cr_num_set(CRNum *a_this, gdouble a_val, enum CRNumType a_type)
cr_num_set: Sets an instance of CRNum.
Definition: cr-num.c:264
cr_num_is_fixed_length
gboolean cr_num_is_fixed_length(CRNum const *a_this)
cr_num_is_fixed_length: @a_this: the current instance of CRNum .
Definition: cr-num.c:287
NUM_LENGTH_PC
@ NUM_LENGTH_PC
Definition: cr-num.h:65
cr_num_to_string
guchar * cr_num_to_string(CRNum const *a_this)
cr_num_to_string: @a_this: the current instance of CRNum.
Definition: cr-num.c:95
NUM_ANGLE_DEG
@ NUM_ANGLE_DEG
Definition: cr-num.h:66
NUM_ANGLE_GRAD
@ NUM_ANGLE_GRAD
Definition: cr-num.h:68
NUM_LENGTH_PT
@ NUM_LENGTH_PT
Definition: cr-num.h:64
CR_BAD_PARAM_ERROR
@ CR_BAD_PARAM_ERROR
Definition: cr-utils.h:45
NUM_TIME_MS
@ NUM_TIME_MS
Definition: cr-num.h:69
NUM_TIME_S
@ NUM_TIME_S
Definition: cr-num.h:70
NUM_LENGTH_CM
@ NUM_LENGTH_CM
Definition: cr-num.h:62
NUM_LENGTH_PX
@ NUM_LENGTH_PX
Definition: cr-num.h:60
_CRNum::val
gdouble val
Definition: cr-num.h:93
NUM_AUTO
@ NUM_AUTO
Definition: cr-num.h:56
_CRNum::type
enum CRNumType type
Definition: cr-num.h:92
cr_num_dup
CRNum * cr_num_dup(CRNum const *a_this)
cr_num_dup: @a_this: the instance of CRNum to duplicate.
Definition: cr-num.c:237
NUM_GENERIC
@ NUM_GENERIC
Definition: cr-num.h:57
CR_OK
@ CR_OK
Definition: cr-utils.h:44
_CRNum
An abstraction of a number (num) as defined in the css2 spec.
Definition: cr-num.h:90
cr_num_copy
enum CRStatus cr_num_copy(CRNum *a_dest, CRNum const *a_src)
cr_num_copy: @a_src: the instance of CRNum to copy.
Definition: cr-num.c:218
NUM_FREQ_HZ
@ NUM_FREQ_HZ
Definition: cr-num.h:71
cr_num_destroy
void cr_num_destroy(CRNum *a_this)
cr_num_destroy: @a_this: the this pointer of the current instance of CRNum.
Definition: cr-num.c:308
NUM_PERCENTAGE
@ NUM_PERCENTAGE
Definition: cr-num.h:73
NUM_LENGTH_EX
@ NUM_LENGTH_EX
Definition: cr-num.h:59
NUM_LENGTH_EM
@ NUM_LENGTH_EM
Definition: cr-num.h:58
cr-num.h
NUM_ANGLE_RAD
@ NUM_ANGLE_RAD
Definition: cr-num.h:67
NUM_INHERIT
@ NUM_INHERIT
Definition: cr-num.h:74
cr_num_new
CRNum * cr_num_new(void)
@CRNum:
Definition: cr-num.c:44
cr_num_new_with_val
CRNum * cr_num_new_with_val(gdouble a_val, enum CRNumType a_type)
cr_num_new_with_val: @a_val: the numerical value of the number.
Definition: cr-num.c:71
CRNumType
CRNumType
The different types of numbers.
Definition: cr-num.h:54
CRStatus
CRStatus
The status type returned by the methods of the croco library.
Definition: cr-utils.h:43
cr_utils_trace_info
#define cr_utils_trace_info(a_msg)
Traces an info message.
Definition: cr-utils.h:127