(root)/
gettext-0.22.4/
libtextstyle/
lib/
libcroco/
cr-fonts.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 
      19   * the GNU Lesser General Public
      20   * License as published by the Free Software Foundation.
      21   *
      22   * This program is distributed in the hope that it will be useful,
      23   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      24   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      25   * GNU General Public License for more details.
      26   *
      27   * You should have received a copy of the 
      28   * GNU Lesser General Public License
      29   * along with this program; if not, write to the Free Software
      30   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
      31   * USA
      32   */
      33  
      34  #include <config.h>
      35  #include "cr-fonts.h"
      36  #include <string.h>
      37  
      38  static enum CRStatus
      39  cr_font_family_to_string_real (CRFontFamily const * a_this,
      40                                 gboolean a_walk_list, GString ** a_string)
      41  {
      42          guchar const *name = NULL;
      43          enum CRStatus result = CR_OK;
      44  
      45          if (!*a_string) {
      46                  *a_string = g_string_new (NULL);
      47                  g_return_val_if_fail (*a_string,
      48                                        CR_INSTANCIATION_FAILED_ERROR);
      49          }
      50  
      51          if (!a_this) {
      52                  g_string_append (*a_string, "NULL");
      53                  return CR_OK;
      54          }
      55  
      56          switch (a_this->type) {
      57          case FONT_FAMILY_SANS_SERIF:
      58                  name = (guchar const *) "sans-serif";
      59                  break;
      60  
      61          case FONT_FAMILY_SERIF:
      62                  name = (guchar const *) "sans-serif";
      63                  break;
      64  
      65          case FONT_FAMILY_CURSIVE:
      66                  name = (guchar const *) "cursive";
      67                  break;
      68  
      69          case FONT_FAMILY_FANTASY:
      70                  name = (guchar const *) "fantasy";
      71                  break;
      72  
      73          case FONT_FAMILY_MONOSPACE:
      74                  name = (guchar const *) "monospace";
      75                  break;
      76  
      77          case FONT_FAMILY_NON_GENERIC:
      78                  name = (guchar const *) a_this->name;
      79                  break;
      80  
      81          default:
      82                  name = NULL;
      83                  break;
      84          }
      85  
      86          if (name) {
      87                  if (a_this->prev) {
      88                          g_string_append_printf (*a_string, ", %s", name);
      89                  } else {
      90                          g_string_append (*a_string, (const gchar *) name);
      91                  }
      92          }
      93          if (a_walk_list == TRUE && a_this->next) {
      94                  result = cr_font_family_to_string_real (a_this->next,
      95                                                          TRUE, a_string);
      96          }
      97          return result;
      98  }
      99  
     100  static const gchar *
     101  cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize
     102                                              a_code)
     103  {
     104          gchar const *str = NULL;
     105  
     106          switch (a_code) {
     107          case FONT_SIZE_XX_SMALL:
     108                  str = "xx-small";
     109                  break;
     110          case FONT_SIZE_X_SMALL:
     111                  str = "x-small";
     112                  break;
     113          case FONT_SIZE_SMALL:
     114                  str = "small";
     115                  break;
     116          case FONT_SIZE_MEDIUM:
     117                  str = "medium";
     118                  break;
     119          case FONT_SIZE_LARGE:
     120                  str = "large";
     121                  break;
     122          case FONT_SIZE_X_LARGE:
     123                  str = "x-large";
     124                  break;
     125          case FONT_SIZE_XX_LARGE:
     126                  str = "xx-large";
     127                  break;
     128          default:
     129                  str = "unknown absolute font size value";
     130          }
     131          return str;
     132  }
     133  
     134  static const gchar *
     135  cr_relative_font_size_to_string (enum CRRelativeFontSize a_code)
     136  {
     137          gchar const *str = NULL;
     138  
     139          switch (a_code) {
     140          case FONT_SIZE_LARGER:
     141                  str = "larger";
     142                  break;
     143          case FONT_SIZE_SMALLER:
     144                  str = "smaller";
     145                  break;
     146          default:
     147                  str = "unknown relative font size value";
     148                  break;
     149          }
     150          return str;
     151  }
     152  
     153  /**
     154   * cr_font_family_new:
     155   * @a_type: the type of font family to create.
     156   * @a_name: the name of the font family.
     157   *
     158   * create a font family.
     159   *
     160   * Returns the newly built font family.
     161   */
     162  CRFontFamily *
     163  cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name)
     164  {
     165          CRFontFamily *result = NULL;
     166  
     167          result = g_try_malloc (sizeof (CRFontFamily));
     168  
     169          if (!result) {
     170                  cr_utils_trace_info ("Out of memory");
     171                  return NULL;
     172          }
     173  
     174          memset (result, 0, sizeof (CRFontFamily));
     175          result->type = a_type;
     176  
     177          cr_font_family_set_name (result, a_name);
     178  
     179          return result;
     180  }
     181  
     182  /**
     183   * cr_font_family_to_string:
     184   * @a_this: the current instance of #CRFontFamily.
     185   * @a_walk_font_family_list: wether the serialize the entire list.
     186   *
     187   * Returns the seriliazed font family. The caller has to free it using
     188   * g_free().
     189   */
     190  guchar *
     191  cr_font_family_to_string (CRFontFamily const * a_this,
     192                            gboolean a_walk_font_family_list)
     193  {
     194          enum CRStatus status = CR_OK;
     195          guchar *result = NULL;
     196          GString *stringue = NULL;
     197  
     198          if (!a_this) {
     199                  result = (guchar *) g_strdup ("NULL");
     200                  g_return_val_if_fail (result, NULL);
     201                  return result;
     202          }
     203          status = cr_font_family_to_string_real (a_this,
     204                                                  a_walk_font_family_list,
     205                                                  &stringue);
     206  
     207          if (status == CR_OK && stringue) {
     208                  result = (guchar *) stringue->str;
     209                  g_string_free (stringue, FALSE);
     210                  stringue = NULL;
     211  
     212          } else {
     213                  if (stringue) {
     214                          g_string_free (stringue, TRUE);
     215                          stringue = NULL;
     216                  }
     217          }
     218  
     219          return result;
     220  }
     221  
     222  /**
     223   * cr_font_family_set_name:
     224   * @a_this: the current instance of #CRFontFamily.
     225   * @a_name: the new name
     226   *
     227   * Returns CR_OK upon sucessful completion, an error code otherwise.
     228   */
     229  enum CRStatus
     230  cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name)
     231  {
     232          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
     233  
     234          /*
     235           *only non generic font families can have a name
     236           */
     237  
     238          if (a_this->type != FONT_FAMILY_NON_GENERIC) {
     239                  return CR_BAD_PARAM_ERROR;
     240          }
     241  
     242          if (a_this->name) {
     243                  g_free (a_this->name);
     244                  a_this->name = NULL;
     245          }
     246  
     247          a_this->name = a_name;
     248          return CR_OK;
     249  }
     250  
     251  /**
     252   * cr_font_family_append:
     253   * @a_this: the current instance of #CRFontFamily.
     254   * @a_family_to_append: the font family to append to the list
     255   *
     256   * Returns the new font family list.
     257   */
     258  CRFontFamily *
     259  cr_font_family_append (CRFontFamily * a_this,
     260                         CRFontFamily * a_family_to_append)
     261  {
     262          CRFontFamily *cur_ff = NULL;
     263  
     264          g_return_val_if_fail (a_family_to_append, NULL);
     265  
     266          if (!a_this)
     267                  return a_family_to_append;
     268  
     269          for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
     270  
     271          cur_ff->next = a_family_to_append;
     272          a_family_to_append->prev = cur_ff;
     273  
     274          return a_this;
     275  
     276  }
     277  
     278  /**
     279   * cr_font_family_prepend:
     280   * @a_this: the current instance #CRFontFamily.
     281   * @a_family_to_prepend: the font family to prepend to the list.
     282   *
     283   * Returns the font family list.
     284   */
     285  CRFontFamily *
     286  cr_font_family_prepend (CRFontFamily * a_this,
     287                          CRFontFamily * a_family_to_prepend)
     288  {
     289          g_return_val_if_fail (a_this && a_family_to_prepend, NULL);
     290  
     291          if (!a_this)
     292                  return a_family_to_prepend;
     293  
     294          a_family_to_prepend->next = a_this;
     295          a_this->prev = a_family_to_prepend;
     296  
     297          return a_family_to_prepend;
     298  }
     299  
     300  /**
     301   * cr_font_family_destroy:
     302   * @a_this: the current instance of #CRFontFamily.
     303   *
     304   * Returns CR_OK upon sucessful completion, an error code otherwise.
     305   */
     306  enum CRStatus
     307  cr_font_family_destroy (CRFontFamily * a_this)
     308  {
     309          CRFontFamily *cur_ff = NULL;
     310  
     311          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
     312  
     313          for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ;
     314  
     315          for (; cur_ff; cur_ff = cur_ff->prev) {
     316                  if (a_this->name) {
     317                          g_free (a_this->name);
     318                          a_this->name = NULL;
     319                  }
     320  
     321                  if (cur_ff->next) {
     322                          g_free (cur_ff->next);
     323  
     324                  }
     325  
     326                  if (cur_ff->prev == NULL) {
     327                          g_free (a_this);
     328                  }
     329          }
     330  
     331          return CR_OK;
     332  }
     333  
     334  /***************************************************
     335   *'font-size' manipulation functions definitions
     336   ***************************************************/
     337  
     338  /**
     339   * cr_font_size_new:
     340   *
     341   * Returns the newly created font size.
     342   */
     343  CRFontSize *
     344  cr_font_size_new (void)
     345  {
     346          CRFontSize *result = NULL;
     347  
     348          result = g_try_malloc (sizeof (CRFontSize));
     349          if (!result) {
     350                  cr_utils_trace_info ("Out of memory");
     351                  return NULL;
     352          }
     353          memset (result, 0, sizeof (CRFontSize));
     354  
     355          return result;
     356  }
     357  
     358  /**
     359   * cr_font_size_clear:
     360   * @a_this: the current instance of #CRFontSize
     361   *
     362   * Returns CR_OK upon successful completion, an error code otherwise.
     363   */
     364  enum CRStatus
     365  cr_font_size_clear (CRFontSize * a_this)
     366  {
     367          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
     368  
     369          switch (a_this->type) {
     370          case PREDEFINED_ABSOLUTE_FONT_SIZE:
     371          case RELATIVE_FONT_SIZE:
     372          case INHERITED_FONT_SIZE:
     373                  memset (a_this, 0, sizeof (CRFontSize));
     374                  break;
     375  
     376          case ABSOLUTE_FONT_SIZE:
     377                  memset (a_this, 0, sizeof (CRFontSize));
     378                  break;
     379  
     380          default:
     381                  return CR_UNKNOWN_TYPE_ERROR;
     382          }
     383  
     384          return CR_OK;
     385  }
     386  
     387  /**
     388   * cr_font_size_copy:
     389   * @a_dst: the destination #CRFontSize (where to copy to).
     390   * @a_src: the source #CRFontSize (where to copy from).
     391   *
     392   * Returns CR_OK upon successful completion, an error code otherwise.
     393   */
     394  enum CRStatus
     395  cr_font_size_copy (CRFontSize * a_dst, CRFontSize const * a_src)
     396  {
     397          g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR);
     398  
     399          switch (a_src->type) {
     400          case PREDEFINED_ABSOLUTE_FONT_SIZE:
     401          case RELATIVE_FONT_SIZE:
     402          case INHERITED_FONT_SIZE:
     403                  cr_font_size_clear (a_dst);
     404                  memcpy (a_dst, a_src, sizeof (CRFontSize));
     405                  break;
     406  
     407          case ABSOLUTE_FONT_SIZE:
     408                  cr_font_size_clear (a_dst);
     409                  cr_num_copy (&a_dst->value.absolute,
     410                               &a_src->value.absolute);
     411                  a_dst->type = a_src->type;
     412                  break;
     413  
     414          default:
     415                  return CR_UNKNOWN_TYPE_ERROR;
     416          }
     417          return CR_OK;
     418  }
     419  
     420  /**
     421   * cr_font_size_set_predefined_absolute_font_size:
     422   * @a_this: the current instance of #CRFontSize.
     423   * @a_predefined: what to set.
     424   *
     425   * Returns CR_OK upon sucessful completion, an error code otherwise.
     426   */
     427  enum CRStatus 
     428  cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, 
     429                                                  enum CRPredefinedAbsoluteFontSize a_predefined)
     430  {
     431          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
     432          g_return_val_if_fail (a_predefined >= FONT_SIZE_XX_SMALL
     433                                && a_predefined < NB_PREDEFINED_ABSOLUTE_FONT_SIZES,
     434                                CR_BAD_PARAM_ERROR) ;
     435  
     436          a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ;
     437          a_this->value.predefined = a_predefined ;
     438  
     439          return CR_OK ;
     440  }
     441  
     442  /**
     443   * cr_font_size_set_relative_font_size:
     444   * @a_this: the current instance of #CRFontSize
     445   * @a_relative: the new relative font size
     446   *
     447   * Returns CR_OK upon successful completion, an error code otherwise.
     448   */
     449  enum CRStatus 
     450  cr_font_size_set_relative_font_size (CRFontSize *a_this,
     451                                       enum CRRelativeFontSize a_relative)
     452  {
     453          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
     454          g_return_val_if_fail (a_relative >= FONT_SIZE_LARGER
     455                                && a_relative < NB_RELATIVE_FONT_SIZE,
     456                                CR_BAD_PARAM_ERROR) ;
     457          
     458          a_this->type = RELATIVE_FONT_SIZE ;
     459          a_this->value.relative = a_relative ;
     460          return CR_OK ;
     461  }
     462  
     463  /**
     464   * cr_font_size_set_absolute_font_size:
     465   * @a_this: the current instance of #CRFontSize
     466   * @a_num_type: the type of number to set.
     467   * @a_value: the actual value to set.
     468   *
     469   * Returns CR_OK upon succesful completion, an error code otherwise.
     470   */
     471  enum CRStatus 
     472  cr_font_size_set_absolute_font_size (CRFontSize *a_this,
     473                                       enum CRNumType a_num_type,
     474                                       gdouble a_value)
     475  {
     476          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
     477          g_return_val_if_fail (a_num_type >= NUM_AUTO
     478                                && a_num_type < NB_NUM_TYPE,
     479                                CR_BAD_PARAM_ERROR) ;
     480  
     481          a_this->type = ABSOLUTE_FONT_SIZE ;
     482          cr_num_set (&a_this->value.absolute,
     483                      a_value, a_num_type) ;        
     484          return CR_OK ;
     485  }
     486  
     487  /**
     488   * cr_font_size_set_to_inherit:
     489   * @a_this: the current instance of #CRFontSize 
     490   *
     491   * Returns CR_OK upon succesful completion, an error code otherwise.
     492   */
     493  enum CRStatus
     494  cr_font_size_set_to_inherit (CRFontSize *a_this)
     495  {
     496          g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ;
     497  
     498          cr_font_size_clear (a_this) ;
     499          a_this->type = INHERITED_FONT_SIZE ;
     500  
     501          return CR_OK ;
     502  }
     503  
     504  /**
     505   * cr_font_size_is_set_to_inherit:
     506   * @a_this: the current instance of #CRFontSize.
     507   *
     508   * Returns TRUE if the current instance is set to 'inherit'. 
     509   */
     510  gboolean
     511  cr_font_size_is_set_to_inherit (CRFontSize const *a_this)
     512  {
     513          g_return_val_if_fail (a_this, FALSE) ;
     514  
     515          return a_this->type == INHERITED_FONT_SIZE ;
     516  }
     517  
     518  /**
     519   * cr_font_size_to_string:
     520   * @a_this: the current instance of #CRFontSize
     521   *
     522   * Returns the serialized form of #CRFontSize. The returned string
     523   * has to bee freed using g_free().
     524   */
     525  gchar *
     526  cr_font_size_to_string (CRFontSize const * a_this)
     527  {
     528          gchar *str = NULL;
     529  
     530          if (!a_this) {
     531                  str = g_strdup ("NULL");
     532                  g_return_val_if_fail (str, NULL);
     533                  return str;
     534          }
     535          switch (a_this->type) {
     536          case PREDEFINED_ABSOLUTE_FONT_SIZE:
     537                  str = g_strdup (cr_predefined_absolute_font_size_to_string
     538                                  (a_this->value.predefined));
     539                  break;
     540          case ABSOLUTE_FONT_SIZE:
     541                  str = (gchar *) cr_num_to_string (&a_this->value.absolute);
     542                  break;
     543          case RELATIVE_FONT_SIZE:
     544                  str = g_strdup (cr_relative_font_size_to_string
     545                                  (a_this->value.relative));
     546                  break;
     547          case INHERITED_FONT_SIZE:
     548                  str = g_strdup ("inherit");
     549                  break;
     550          default:
     551                  break;
     552          }
     553          return str;
     554  }
     555  
     556  /**
     557   * cr_font_size_get_smaller_predefined:
     558   * @a_font_size: the font size to consider.
     559   * @a_smaller_size: out parameter. The a smaller value than @a_font_size. 
     560   */
     561  void 
     562  cr_font_size_get_smaller_predefined_font_size 
     563  				(enum CRPredefinedAbsoluteFontSize a_font_size,
     564  			         enum CRPredefinedAbsoluteFontSize *a_smaller_size)
     565  {
     566          enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
     567  
     568          g_return_if_fail (a_smaller_size) ;
     569          g_return_if_fail (a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES
     570                            && a_font_size >= FONT_SIZE_XX_SMALL) ;
     571  
     572          switch (a_font_size) {
     573          case FONT_SIZE_XX_SMALL:
     574                  result =  FONT_SIZE_XX_SMALL ;
     575                  break ;
     576          case FONT_SIZE_X_SMALL:
     577                  result =  FONT_SIZE_XX_SMALL ;
     578                  break ;
     579          case FONT_SIZE_SMALL:
     580                  result =  FONT_SIZE_X_SMALL;
     581                  break ;
     582          case FONT_SIZE_MEDIUM:
     583                  result =  FONT_SIZE_SMALL;
     584                  break ;
     585          case FONT_SIZE_LARGE:
     586                  result =  FONT_SIZE_MEDIUM;
     587                  break ;
     588          case FONT_SIZE_X_LARGE:
     589                  result =  FONT_SIZE_LARGE;
     590                  break ;
     591          case FONT_SIZE_XX_LARGE:
     592                  result =  FONT_SIZE_XX_LARGE;
     593                  break ;
     594  	case FONT_SIZE_INHERIT:
     595                  cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ;                
     596                  result =  FONT_SIZE_MEDIUM ;
     597                  break ;
     598          default:
     599                  cr_utils_trace_info ("Unknown FONT_SIZE") ;
     600                  result = FONT_SIZE_MEDIUM ;
     601                  break ;
     602          }
     603          *a_smaller_size = result ;
     604  }
     605  
     606  
     607  /**
     608   * cr_font_size_get_larger_predefined_font_size:
     609   * @a_font_size: the font size to consider.
     610   * @a_larger_size: out parameter. the font size considered larger than
     611   * @a_font_size.
     612   *
     613   */
     614  void 
     615  cr_font_size_get_larger_predefined_font_size 
     616  			(enum CRPredefinedAbsoluteFontSize a_font_size,
     617  		         enum CRPredefinedAbsoluteFontSize *a_larger_size)
     618  {
     619          enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ;
     620          
     621          g_return_if_fail (a_larger_size) ;
     622          g_return_if_fail (a_font_size >= FONT_SIZE_XX_SMALL 
     623                            && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ;
     624  
     625          switch (a_font_size) {
     626          case FONT_SIZE_XX_SMALL:
     627                  result =  FONT_SIZE_X_SMALL ;
     628                  break ;
     629          case FONT_SIZE_X_SMALL:
     630                  result =  FONT_SIZE_SMALL ;
     631                  break ;
     632          case FONT_SIZE_SMALL:
     633                  result =  FONT_SIZE_MEDIUM;
     634                  break ;
     635          case FONT_SIZE_MEDIUM:
     636                  result =  FONT_SIZE_LARGE;
     637                  break ;
     638          case FONT_SIZE_LARGE:
     639                  result =  FONT_SIZE_X_LARGE;
     640                  break ;
     641          case FONT_SIZE_X_LARGE:
     642                  result =  FONT_SIZE_XX_LARGE ;
     643                  break ;
     644          case FONT_SIZE_XX_LARGE:
     645                  result =  FONT_SIZE_XX_LARGE;
     646                  break ;
     647  	case FONT_SIZE_INHERIT:
     648                  cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ;                
     649                  result =  FONT_SIZE_MEDIUM ;
     650                  break ;
     651          default:
     652                  cr_utils_trace_info ("Unknown FONT_SIZE") ;
     653                  result = FONT_SIZE_MEDIUM ;
     654                  break ;
     655          }
     656          *a_larger_size = result ;
     657  }
     658  
     659  /**
     660   * cr_font_size_is_predefined_absolute_font_size:
     661   * @a_font_size: the font size to consider.
     662   *
     663   * Returns TRUE if the instance is an predefined absolute font size, FALSE
     664   * otherwise.
     665   */
     666  gboolean
     667  cr_font_size_is_predefined_absolute_font_size 
     668  				(enum CRPredefinedAbsoluteFontSize a_font_size)
     669  {
     670          if (a_font_size >= FONT_SIZE_XX_SMALL
     671              && a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) {
     672                  return TRUE ;
     673          } else {
     674                  return FALSE ;
     675          }
     676  }
     677  
     678  /**
     679   * cr_font_size_adjust_to_string:
     680   * @a_this: the instance of #CRFontSizeAdjust.
     681   *
     682   * Returns the serialized form of #CRFontSizeAdjust
     683   */
     684  gchar *
     685  cr_font_size_adjust_to_string (CRFontSizeAdjust const * a_this)
     686  {
     687          gchar *str = NULL;
     688  
     689          if (!a_this) {
     690                  str = g_strdup ("NULL");
     691                  g_return_val_if_fail (str, NULL);
     692                  return str;
     693          }
     694  
     695          switch (a_this->type) {
     696          case FONT_SIZE_ADJUST_NONE:
     697                  str = g_strdup ("none");
     698                  break;
     699          case FONT_SIZE_ADJUST_NUMBER:
     700                  if (a_this->num)
     701                          str = (gchar *) cr_num_to_string (a_this->num);
     702                  else
     703                          str = g_strdup ("unknown font-size-adjust property value"); /* Should raise an error no?*/
     704                  break;
     705          case FONT_SIZE_ADJUST_INHERIT:
     706                  str = g_strdup ("inherit");
     707          }
     708          return str;
     709  }
     710  
     711  /**
     712   * cr_font_style_to_string:
     713   * @a_code: the current instance of #CRFontStyle .
     714   *
     715   * Returns the serialized #CRFontStyle. The caller must free the returned
     716   * string using g_free().
     717   */
     718  const gchar *
     719  cr_font_style_to_string (enum CRFontStyle a_code)
     720  {
     721          gchar *str = NULL;
     722  
     723          switch (a_code) {
     724          case FONT_STYLE_NORMAL:
     725                  str = (gchar *) "normal";
     726                  break;
     727          case FONT_STYLE_ITALIC:
     728                  str = (gchar *) "italic";
     729                  break;
     730          case FONT_STYLE_OBLIQUE:
     731                  str = (gchar *) "oblique";
     732                  break;
     733          case FONT_STYLE_INHERIT:
     734                  str = (gchar *) "inherit";
     735                  break;
     736          default:
     737                  str = (gchar *) "unknown font style value";
     738                  break;
     739          }
     740          return str;
     741  }
     742  
     743  /**
     744   * cr_font_variant_to_string:
     745   * @a_code: the current instance of #CRFontVariant.
     746   *
     747   * Returns the serialized form of #CRFontVariant. The caller has
     748   * to free the returned string using g_free().
     749   */
     750  const gchar *
     751  cr_font_variant_to_string (enum CRFontVariant a_code)
     752  {
     753          gchar *str = NULL;
     754  
     755          switch (a_code) {
     756          case FONT_VARIANT_NORMAL:
     757                  str = (gchar *) "normal";
     758                  break;
     759          case FONT_VARIANT_SMALL_CAPS:
     760                  str = (gchar *) "small-caps";
     761                  break;
     762          case FONT_VARIANT_INHERIT:
     763                  str = (gchar *) "inherit";
     764                  break;
     765          }
     766          return str;
     767  }
     768  
     769  /**
     770   * cr_font_weight_get_bolder:
     771   * @a_weight: the #CRFontWeight to consider.
     772   *
     773   * Returns a font weight bolder than @a_weight
     774   */
     775  enum CRFontWeight
     776  cr_font_weight_get_bolder (enum CRFontWeight a_weight)
     777  {
     778          if (a_weight == FONT_WEIGHT_INHERIT) {
     779                  cr_utils_trace_info ("can't return a bolder weight for FONT_WEIGHT_INHERIT") ;
     780                  return a_weight;
     781          } else if (a_weight >= FONT_WEIGHT_900) {
     782                  return FONT_WEIGHT_900 ;
     783          } else if (a_weight < FONT_WEIGHT_NORMAL) {
     784                  return FONT_WEIGHT_NORMAL ;
     785          } else if (a_weight == FONT_WEIGHT_BOLDER
     786                     || a_weight == FONT_WEIGHT_LIGHTER) {
     787                  cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ;
     788                  return FONT_WEIGHT_NORMAL ;
     789          } else {
     790                  return a_weight << 1 ;
     791          }
     792  }
     793  
     794  /**
     795   * cr_font_weight_to_string:
     796   * @a_code: the font weight to consider.
     797   *
     798   * Returns the serialized form of #CRFontWeight.
     799   */
     800  const gchar *
     801  cr_font_weight_to_string (enum CRFontWeight a_code)
     802  {
     803          gchar *str = NULL;
     804  
     805          switch (a_code) {
     806          case FONT_WEIGHT_NORMAL:
     807                  str = (gchar *) "normal";
     808                  break;
     809          case FONT_WEIGHT_BOLD:
     810                  str = (gchar *) "bold";
     811                  break;
     812          case FONT_WEIGHT_BOLDER:
     813                  str = (gchar *) "bolder";
     814                  break;
     815          case FONT_WEIGHT_LIGHTER:
     816                  str = (gchar *) "lighter";
     817                  break;
     818          case FONT_WEIGHT_100:
     819                  str = (gchar *) "100";
     820                  break;
     821          case FONT_WEIGHT_200:
     822                  str = (gchar *) "200";
     823                  break;
     824          case FONT_WEIGHT_300:
     825                  str = (gchar *) "300";
     826                  break;
     827          case FONT_WEIGHT_400:
     828                  str = (gchar *) "400";
     829                  break;
     830          case FONT_WEIGHT_500:
     831                  str = (gchar *) "500";
     832                  break;
     833          case FONT_WEIGHT_600:
     834                  str = (gchar *) "600";
     835                  break;
     836          case FONT_WEIGHT_700:
     837                  str = (gchar *) "700";
     838                  break;
     839          case FONT_WEIGHT_800:
     840                  str = (gchar *) "800";
     841                  break;
     842          case FONT_WEIGHT_900:
     843                  str = (gchar *) "900";
     844                  break;
     845          case FONT_WEIGHT_INHERIT:
     846                  str = (gchar *) "inherit";
     847                  break;
     848          default:
     849                  str = (gchar *) "unknown font-weight property value";
     850                  break;
     851          }
     852          return str;
     853  }
     854  
     855  /**
     856   * cr_font_stretch_to_string:
     857   * @a_code: the instance of #CRFontStretch to consider.
     858   *
     859   * Returns the serialized form of #CRFontStretch.
     860   */
     861  const gchar *
     862  cr_font_stretch_to_string (enum CRFontStretch a_code)
     863  {
     864          gchar *str = NULL;
     865  
     866          switch (a_code) {
     867          case FONT_STRETCH_NORMAL:
     868                  str = (gchar *) "normal";
     869                  break;
     870          case FONT_STRETCH_WIDER:
     871                  str = (gchar *) "wider";
     872                  break;
     873          case FONT_STRETCH_NARROWER:
     874                  str = (gchar *) "narrower";
     875                  break;
     876          case FONT_STRETCH_ULTRA_CONDENSED:
     877                  str = (gchar *) "ultra-condensed";
     878                  break;
     879          case FONT_STRETCH_EXTRA_CONDENSED:
     880                  str = (gchar *) "extra-condensed";
     881                  break;
     882          case FONT_STRETCH_CONDENSED:
     883                  str = (gchar *) "condensed";
     884                  break;
     885          case FONT_STRETCH_SEMI_CONDENSED:
     886                  str = (gchar *) "semi-condensed";
     887                  break;
     888          case FONT_STRETCH_SEMI_EXPANDED:
     889                  str = (gchar *) "semi-expanded";
     890                  break;
     891          case FONT_STRETCH_EXPANDED:
     892                  str = (gchar *) "expanded";
     893                  break;
     894          case FONT_STRETCH_EXTRA_EXPANDED:
     895                  str = (gchar *) "extra-expaned";
     896                  break;
     897          case FONT_STRETCH_ULTRA_EXPANDED:
     898                  str = (gchar *) "ultra-expanded";
     899                  break;
     900          case FONT_STRETCH_INHERIT:
     901                  str = (gchar *) "inherit";
     902                  break;
     903          }
     904          return str;
     905  }
     906  
     907  /**
     908   * cr_font_size_destroy:
     909   * @a_font_size: the font size to destroy
     910   *
     911   */
     912  void
     913  cr_font_size_destroy (CRFontSize * a_font_size)
     914  {
     915          g_return_if_fail (a_font_size);
     916  
     917          g_free (a_font_size) ;
     918  }
     919  
     920  /*******************************************************
     921   *'font-size-adjust' manipulation function definition
     922   *******************************************************/
     923  
     924  /**
     925   * cr_font_size_adjust_new:
     926   *
     927   * Returns a newly built instance of #CRFontSizeAdjust
     928   */
     929  CRFontSizeAdjust *
     930  cr_font_size_adjust_new (void)
     931  {
     932          CRFontSizeAdjust *result = NULL;
     933  
     934          result = g_try_malloc (sizeof (CRFontSizeAdjust));
     935          if (!result) {
     936                  cr_utils_trace_info ("Out of memory");
     937                  return NULL;
     938          }
     939          memset (result, 0, sizeof (CRFontSizeAdjust));
     940  
     941          return result;
     942  }
     943  
     944  /**
     945   * cr_font_size_adjust_destroy:
     946   * @a_this: the current instance of #CRFontSizeAdjust.
     947   *
     948   */
     949  void
     950  cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this)
     951  {
     952          g_return_if_fail (a_this);
     953  
     954          if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) {
     955                  cr_num_destroy (a_this->num);
     956                  a_this->num = NULL;
     957          }
     958  }