(root)/
gettext-0.22.4/
libtextstyle/
lib/
libcroco/
cr-num.c
       1  /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
       2  
       3  /* libcroco - Library for parsing and applying CSS
       4   * Copyright (C) 2006-2019 Free Software Foundation, Inc.
       5   *
       6   * This file is not part of the GNU gettext program, but is used with
       7   * GNU gettext.
       8   *
       9   * The original copyright notice is as follows:
      10   */
      11  
      12  /*
      13   * This file is part of The Croco Library
      14   *
      15   * Copyright (C) 2003-2004 Dodji Seketeli.  All Rights Reserved.
      16   *
      17   * This program is free software; you can redistribute it and/or
      18   * modify it under the terms of version 2.1 of the GNU Lesser General Public
      19   * License as published by the Free Software Foundation.
      20   *
      21   * This program is distributed in the hope that it will be useful,
      22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24   * GNU General Public License for more details.
      25   *
      26   * You should have received a copy of the GNU Lesser General Public License
      27   * along with this program; if not, write to the Free Software
      28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      29   * USA
      30   *
      31   * Author: Dodji Seketeli
      32   */
      33  
      34  /**
      35   *@CRNum:
      36   *
      37   *The definition
      38   *of the #CRNum class.
      39   */
      40  
      41  #include <config.h>
      42  #include "cr-num.h"
      43  #include "string.h"
      44  
      45  /**
      46   * cr_num_new:
      47   *
      48   *#CRNum.
      49   *
      50   *Returns the newly built instance of
      51   *#CRNum.
      52   */
      53  CRNum *
      54  cr_num_new (void)
      55  {
      56          CRNum *result = NULL;
      57  
      58          result = g_try_malloc (sizeof (CRNum));
      59  
      60          if (result == NULL) {
      61                  cr_utils_trace_info ("Out of memory");
      62                  return NULL;
      63          }
      64  
      65          memset (result, 0, sizeof (CRNum));
      66  
      67          return result;
      68  }
      69  
      70  /**
      71   * cr_num_new_with_val:
      72   * @a_val: the numerical value of the number.
      73   * @a_type: the type of number.
      74   * 
      75   * A constructor of #CRNum.
      76   *
      77   * Returns the newly built instance of #CRNum or
      78   * NULL if an error arises.
      79   */
      80  CRNum *
      81  cr_num_new_with_val (gdouble a_val, enum CRNumType a_type)
      82  {
      83          CRNum *result = NULL;
      84  
      85          result = cr_num_new ();
      86  
      87          g_return_val_if_fail (result, NULL);
      88  
      89          result->val = a_val;
      90          result->type = a_type;
      91  
      92          return result;
      93  }
      94  
      95  /**
      96   * cr_num_to_string:
      97   *@a_this: the current instance of #CRNum.
      98   *
      99   *Returns the newly built string representation
     100   *of the current instance of #CRNum. The returned
     101   *string is NULL terminated. The caller *must*
     102   *free the returned string.
     103   */
     104  guchar *
     105  cr_num_to_string (CRNum const * a_this)
     106  {
     107          gdouble test_val = 0.0;
     108  
     109          guchar *tmp_char1 = NULL,
     110                  *tmp_char2 = NULL,
     111                  *result = NULL;
     112  
     113          g_return_val_if_fail (a_this, NULL);
     114  
     115          test_val = a_this->val - (glong) a_this->val;
     116  
     117          if (!test_val) {
     118                  tmp_char1 = (guchar *) g_strdup_printf ("%ld", (glong) a_this->val);
     119          } else {
     120                  tmp_char1 = (guchar *) g_new0 (char, G_ASCII_DTOSTR_BUF_SIZE + 1);
     121                  if (tmp_char1 != NULL)
     122                          g_ascii_dtostr ((gchar *) tmp_char1, G_ASCII_DTOSTR_BUF_SIZE, a_this->val);
     123          }
     124  
     125          g_return_val_if_fail (tmp_char1, NULL);
     126  
     127          switch (a_this->type) {
     128          case NUM_LENGTH_EM:
     129                  tmp_char2 = (guchar *) "em";
     130                  break;
     131  
     132          case NUM_LENGTH_EX:
     133                  tmp_char2 = (guchar *) "ex";
     134                  break;
     135  
     136          case NUM_LENGTH_PX:
     137                  tmp_char2 = (guchar *) "px";
     138                  break;
     139  
     140          case NUM_LENGTH_IN:
     141                  tmp_char2 = (guchar *) "in";
     142                  break;
     143  
     144          case NUM_LENGTH_CM:
     145                  tmp_char2 = (guchar *) "cm";
     146                  break;
     147  
     148          case NUM_LENGTH_MM:
     149                  tmp_char2 = (guchar *) "mm";
     150                  break;
     151  
     152          case NUM_LENGTH_PT:
     153                  tmp_char2 = (guchar *) "pt";
     154                  break;
     155  
     156          case NUM_LENGTH_PC:
     157                  tmp_char2 = (guchar *) "pc";
     158                  break;
     159  
     160          case NUM_ANGLE_DEG:
     161                  tmp_char2 = (guchar *) "deg";
     162                  break;
     163  
     164          case NUM_ANGLE_RAD:
     165                  tmp_char2 = (guchar *) "rad";
     166                  break;
     167  
     168          case NUM_ANGLE_GRAD:
     169                  tmp_char2 = (guchar *) "grad";
     170                  break;
     171  
     172          case NUM_TIME_MS:
     173                  tmp_char2 = (guchar *) "ms";
     174                  break;
     175  
     176          case NUM_TIME_S:
     177                  tmp_char2 = (guchar *) "s";
     178                  break;
     179  
     180          case NUM_FREQ_HZ:
     181                  tmp_char2 = (guchar *) "Hz";
     182                  break;
     183  
     184          case NUM_FREQ_KHZ:
     185                  tmp_char2 = (guchar *) "KHz";
     186                  break;
     187  
     188          case NUM_PERCENTAGE:
     189                  tmp_char2 = (guchar *) "%";
     190                  break;
     191          case NUM_INHERIT:
     192                  tmp_char2 = (guchar *) "inherit";
     193                  break ;
     194          case NUM_AUTO:
     195                  tmp_char2 = (guchar *) "auto";
     196                  break ;
     197          case NUM_GENERIC:
     198                  tmp_char2 = NULL ;
     199                  break ;
     200          default:
     201                  tmp_char2 = (guchar *) "unknown";
     202                  break;
     203          }
     204  
     205          if (tmp_char2) {
     206                  result = (guchar *)  g_strconcat ((gchar *) tmp_char1, tmp_char2, NULL);
     207                  g_free (tmp_char1);
     208          } else {
     209                  result = tmp_char1;
     210          }
     211  
     212          return result;
     213  }
     214  
     215  /**
     216   * cr_num_copy:
     217   *@a_src: the instance of #CRNum to copy.
     218   *Must be non NULL.
     219   *@a_dest: the destination of the copy.
     220   *Must be non NULL
     221   *
     222   *Copies an instance of #CRNum.
     223   *
     224   *Returns CR_OK upon successful completion, an
     225   *error code otherwise.
     226   */
     227  enum CRStatus
     228  cr_num_copy (CRNum * a_dest, CRNum const * a_src)
     229  {
     230          g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
     231  
     232          memcpy (a_dest, a_src, sizeof (CRNum));
     233  
     234          return CR_OK;
     235  }
     236  
     237  /**
     238   * cr_num_dup:
     239   *@a_this: the instance of #CRNum to duplicate.
     240   *
     241   *Duplicates an instance of #CRNum
     242   *
     243   *Returns the newly created (duplicated) instance of #CRNum.
     244   *Must be freed by cr_num_destroy().
     245   */
     246  CRNum *
     247  cr_num_dup (CRNum const * a_this)
     248  {
     249          CRNum *result = NULL;
     250          enum CRStatus status = CR_OK;
     251  
     252          g_return_val_if_fail (a_this, NULL);
     253  
     254          result = cr_num_new ();
     255          g_return_val_if_fail (result, NULL);
     256  
     257          status = cr_num_copy (result, a_this);
     258          g_return_val_if_fail (status == CR_OK, NULL);
     259  
     260          return result;
     261  }
     262  
     263  /**
     264   * cr_num_set:
     265   *Sets an instance of #CRNum.
     266   *@a_this: the current instance of #CRNum to be set.
     267   *@a_val: the new numerical value to be hold by the current
     268   *instance of #CRNum
     269   *@a_type: the new type of #CRNum.
     270   *
     271   * Returns CR_OK upon succesful completion, an error code otherwise.
     272   */
     273  enum CRStatus
     274  cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type)
     275  {
     276          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
     277  
     278          a_this->val = a_val;
     279          a_this->type = a_type;
     280  
     281          return CR_OK;
     282  }
     283  
     284  /**
     285   * cr_num_is_fixed_length:
     286   * @a_this: the current instance of #CRNum .
     287   *
     288   *Tests if the current instance of #CRNum is a fixed
     289   *length value or not. Typically a fixed length value
     290   *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC.
     291   *See the definition of #CRNumType to see what we mean.
     292   *
     293   *Returns TRUE if the instance of #CRNum is a fixed length number,
     294   *FALSE otherwise.
     295   */
     296  gboolean
     297  cr_num_is_fixed_length (CRNum const * a_this)
     298  {
     299          gboolean result = FALSE;
     300  
     301          g_return_val_if_fail (a_this, FALSE);
     302  
     303          if (a_this->type >= NUM_LENGTH_EM 
     304              && a_this->type <= NUM_LENGTH_PC) {
     305                  result = TRUE ;
     306          }
     307          return result ;
     308  }
     309  
     310  /**
     311   * cr_num_destroy:
     312   *@a_this: the this pointer of
     313   *the current instance of #CRNum.
     314   *
     315   *The destructor of #CRNum.
     316   */
     317  void
     318  cr_num_destroy (CRNum * a_this)
     319  {
     320          g_return_if_fail (a_this);
     321  
     322          g_free (a_this);
     323  }