Libcroco
|
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 }