Libcroco
cr-num.c
Go to the documentation of this file.
00001 /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
00002 
00003 /*
00004  * This file is part of The Croco Library
00005  *
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of version 2.1 of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00019  * USA
00020  *
00021  * Author: Dodji Seketeli
00022  * See COPYRIGHTS file for copyrights information.
00023  */
00024 
00025 /**
00026  *@CRNum:
00027  *
00028  *The definition
00029  *of the #CRNum class.
00030  */
00031 
00032 #include "cr-num.h"
00033 #include "string.h"
00034 
00035 /**
00036  * cr_num_new:
00037  *
00038  *#CRNum.
00039  *
00040  *Returns the newly built instance of
00041  *#CRNum.
00042  */
00043 CRNum *
00044 cr_num_new (void)
00045 {
00046         CRNum *result = NULL;
00047 
00048         result = g_try_malloc (sizeof (CRNum));
00049 
00050         if (result == NULL) {
00051                 cr_utils_trace_info ("Out of memory");
00052                 return NULL;
00053         }
00054 
00055         memset (result, 0, sizeof (CRNum));
00056 
00057         return result;
00058 }
00059 
00060 /**
00061  * cr_num_new_with_val:
00062  * @a_val: the numerical value of the number.
00063  * @a_type: the type of number.
00064  * 
00065  * A constructor of #CRNum.
00066  *
00067  * Returns the newly built instance of #CRNum or
00068  * NULL if an error arises.
00069  */
00070 CRNum *
00071 cr_num_new_with_val (gdouble a_val, enum CRNumType a_type)
00072 {
00073         CRNum *result = NULL;
00074 
00075         result = cr_num_new ();
00076 
00077         g_return_val_if_fail (result, NULL);
00078 
00079         result->val = a_val;
00080         result->type = a_type;
00081 
00082         return result;
00083 }
00084 
00085 /**
00086  * cr_num_to_string:
00087  *@a_this: the current instance of #CRNum.
00088  *
00089  *Returns the newly built string representation
00090  *of the current instance of #CRNum. The returned
00091  *string is NULL terminated. The caller *must*
00092  *free the returned string.
00093  */
00094 guchar *
00095 cr_num_to_string (CRNum const * a_this)
00096 {
00097         gdouble test_val = 0.0;
00098 
00099         guchar *tmp_char1 = NULL,
00100                 *tmp_char2 = NULL,
00101                 *result = NULL;
00102 
00103         g_return_val_if_fail (a_this, NULL);
00104 
00105         test_val = a_this->val - (glong) a_this->val;
00106 
00107         if (!test_val) {
00108                 tmp_char1 = (guchar *) g_strdup_printf ("%ld", (glong) a_this->val);
00109         } else {
00110                 tmp_char1 = (guchar *) g_new0 (char, G_ASCII_DTOSTR_BUF_SIZE + 1);
00111                 if (tmp_char1 != NULL)
00112                         g_ascii_dtostr ((gchar *) tmp_char1, G_ASCII_DTOSTR_BUF_SIZE, a_this->val);
00113         }
00114 
00115         g_return_val_if_fail (tmp_char1, NULL);
00116 
00117         switch (a_this->type) {
00118         case NUM_LENGTH_EM:
00119                 tmp_char2 = (guchar *) "em";
00120                 break;
00121 
00122         case NUM_LENGTH_EX:
00123                 tmp_char2 = (guchar *) "ex";
00124                 break;
00125 
00126         case NUM_LENGTH_PX:
00127                 tmp_char2 = (guchar *) "px";
00128                 break;
00129 
00130         case NUM_LENGTH_IN:
00131                 tmp_char2 = (guchar *) "in";
00132                 break;
00133 
00134         case NUM_LENGTH_CM:
00135                 tmp_char2 = (guchar *) "cm";
00136                 break;
00137 
00138         case NUM_LENGTH_MM:
00139                 tmp_char2 = (guchar *) "mm";
00140                 break;
00141 
00142         case NUM_LENGTH_PT:
00143                 tmp_char2 = (guchar *) "pt";
00144                 break;
00145 
00146         case NUM_LENGTH_PC:
00147                 tmp_char2 = (guchar *) "pc";
00148                 break;
00149 
00150         case NUM_ANGLE_DEG:
00151                 tmp_char2 = (guchar *) "deg";
00152                 break;
00153 
00154         case NUM_ANGLE_RAD:
00155                 tmp_char2 = (guchar *) "rad";
00156                 break;
00157 
00158         case NUM_ANGLE_GRAD:
00159                 tmp_char2 = (guchar *) "grad";
00160                 break;
00161 
00162         case NUM_TIME_MS:
00163                 tmp_char2 = (guchar *) "ms";
00164                 break;
00165 
00166         case NUM_TIME_S:
00167                 tmp_char2 = (guchar *) "s";
00168                 break;
00169 
00170         case NUM_FREQ_HZ:
00171                 tmp_char2 = (guchar *) "Hz";
00172                 break;
00173 
00174         case NUM_FREQ_KHZ:
00175                 tmp_char2 = (guchar *) "KHz";
00176                 break;
00177 
00178         case NUM_PERCENTAGE:
00179                 tmp_char2 = (guchar *) "%";
00180                 break;
00181         case NUM_INHERIT:
00182                 tmp_char2 = (guchar *) "inherit";
00183                 break ;
00184         case NUM_AUTO:
00185                 tmp_char2 = (guchar *) "auto";
00186                 break ;
00187         case NUM_GENERIC:
00188                 tmp_char2 = NULL ;
00189                 break ;
00190         default:
00191                 tmp_char2 = (guchar *) "unknown";
00192                 break;
00193         }
00194 
00195         if (tmp_char2) {
00196                 result = (guchar *)  g_strconcat ((gchar *) tmp_char1, tmp_char2, NULL);
00197                 g_free (tmp_char1);
00198         } else {
00199                 result = tmp_char1;
00200         }
00201 
00202         return result;
00203 }
00204 
00205 /**
00206  * cr_num_copy:
00207  *@a_src: the instance of #CRNum to copy.
00208  *Must be non NULL.
00209  *@a_dest: the destination of the copy.
00210  *Must be non NULL
00211  *
00212  *Copies an instance of #CRNum.
00213  *
00214  *Returns CR_OK upon successful completion, an
00215  *error code otherwise.
00216  */
00217 enum CRStatus
00218 cr_num_copy (CRNum * a_dest, CRNum const * a_src)
00219 {
00220         g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
00221 
00222         memcpy (a_dest, a_src, sizeof (CRNum));
00223 
00224         return CR_OK;
00225 }
00226 
00227 /**
00228  * cr_num_dup:
00229  *@a_this: the instance of #CRNum to duplicate.
00230  *
00231  *Duplicates an instance of #CRNum
00232  *
00233  *Returns the newly created (duplicated) instance of #CRNum.
00234  *Must be freed by cr_num_destroy().
00235  */
00236 CRNum *
00237 cr_num_dup (CRNum const * a_this)
00238 {
00239         CRNum *result = NULL;
00240         enum CRStatus status = CR_OK;
00241 
00242         g_return_val_if_fail (a_this, NULL);
00243 
00244         result = cr_num_new ();
00245         g_return_val_if_fail (result, NULL);
00246 
00247         status = cr_num_copy (result, a_this);
00248         g_return_val_if_fail (status == CR_OK, NULL);
00249 
00250         return result;
00251 }
00252 
00253 /**
00254  * cr_num_set:
00255  *Sets an instance of #CRNum.
00256  *@a_this: the current instance of #CRNum to be set.
00257  *@a_val: the new numerical value to be hold by the current
00258  *instance of #CRNum
00259  *@a_type: the new type of #CRNum.
00260  *
00261  * Returns CR_OK upon succesful completion, an error code otherwise.
00262  */
00263 enum CRStatus
00264 cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type)
00265 {
00266         g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
00267 
00268         a_this->val = a_val;
00269         a_this->type = a_type;
00270 
00271         return CR_OK;
00272 }
00273 
00274 /**
00275  * cr_num_is_fixed_length:
00276  * @a_this: the current instance of #CRNum .
00277  *
00278  *Tests if the current instance of #CRNum is a fixed
00279  *length value or not. Typically a fixed length value
00280  *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC.
00281  *See the definition of #CRNumType to see what we mean.
00282  *
00283  *Returns TRUE if the instance of #CRNum is a fixed length number,
00284  *FALSE otherwise.
00285  */
00286 gboolean
00287 cr_num_is_fixed_length (CRNum const * a_this)
00288 {
00289         gboolean result = FALSE;
00290 
00291         g_return_val_if_fail (a_this, FALSE);
00292 
00293         if (a_this->type >= NUM_LENGTH_EM 
00294             && a_this->type <= NUM_LENGTH_PC) {
00295                 result = TRUE ;
00296         }
00297         return result ;
00298 }
00299 
00300 /**
00301  * cr_num_destroy:
00302  *@a_this: the this pointer of
00303  *the current instance of #CRNum.
00304  *
00305  *The destructor of #CRNum.
00306  */
00307 void
00308 cr_num_destroy (CRNum * a_this)
00309 {
00310         g_return_if_fail (a_this);
00311 
00312         g_free (a_this);
00313 }