1 /***************************************************************************/
   2 /*                                                                         */
   3 /*  ftpsprop.c                                                             */
   4 /*                                                                         */
   5 /*    Get and set properties of PostScript drivers (body).                 */
   6 /*    See `ftdriver.h' for available properties.                           */
   7 /*                                                                         */
   8 /*  Copyright 2017-2018 by                                                 */
   9 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10 /*                                                                         */
  11 /*  This file is part of the FreeType project, and may only be used,       */
  12 /*  modified, and distributed under the terms of the FreeType project      */
  13 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14 /*  this file you indicate that you have read the license and              */
  15 /*  understand and accept it fully.                                        */
  16 /*                                                                         */
  17 /***************************************************************************/
  18 
  19 
  20 #include <ft2build.h>
  21 #include FT_DRIVER_H
  22 #include FT_INTERNAL_DEBUG_H
  23 #include FT_INTERNAL_POSTSCRIPT_AUX_H
  24 #include FT_INTERNAL_OBJECTS_H
  25 #include FT_INTERNAL_POSTSCRIPT_PROPS_H
  26 
  27 
  28   /*************************************************************************/
  29   /*                                                                       */
  30   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  31   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  32   /* messages during execution.                                            */
  33   /*                                                                       */
  34 #undef  FT_COMPONENT
  35 #define FT_COMPONENT  trace_psprops
  36 
  37 
  38   FT_BASE_CALLBACK_DEF( FT_Error )
  39   ps_property_set( FT_Module    module,         /* PS_Driver */
  40                    const char*  property_name,
  41                    const void*  value,
  42                    FT_Bool      value_is_string )
  43   {
  44     FT_Error   error  = FT_Err_Ok;
  45     PS_Driver  driver = (PS_Driver)module;
  46 
  47 #ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
  48     FT_UNUSED( value_is_string );
  49 #endif
  50 
  51 
  52     if ( !ft_strcmp( property_name, "darkening-parameters" ) )
  53     {
  54       FT_Int*  darken_params;
  55       FT_Int   x1, y1, x2, y2, x3, y3, x4, y4;
  56 
  57 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
  58       FT_Int   dp[8];
  59 
  60 
  61       if ( value_is_string )
  62       {
  63         const char*  s = (const char*)value;
  64         char*        ep;
  65         int          i;
  66 
  67 
  68         /* eight comma-separated numbers */
  69         for ( i = 0; i < 7; i++ )
  70         {
  71           dp[i] = (FT_Int)ft_strtol( s, &ep, 10 );
  72           if ( *ep != ',' || s == ep )
  73             return FT_THROW( Invalid_Argument );
  74 
  75           s = ep + 1;
  76         }
  77 
  78         dp[7] = (FT_Int)ft_strtol( s, &ep, 10 );
  79         if ( !( *ep == '\0' || *ep == ' ' ) || s == ep )
  80           return FT_THROW( Invalid_Argument );
  81 
  82         darken_params = dp;
  83       }
  84       else
  85 #endif
  86         darken_params = (FT_Int*)value;
  87 
  88       x1 = darken_params[0];
  89       y1 = darken_params[1];
  90       x2 = darken_params[2];
  91       y2 = darken_params[3];
  92       x3 = darken_params[4];
  93       y3 = darken_params[5];
  94       x4 = darken_params[6];
  95       y4 = darken_params[7];
  96 
  97       if ( x1 < 0   || x2 < 0   || x3 < 0   || x4 < 0   ||
  98            y1 < 0   || y2 < 0   || y3 < 0   || y4 < 0   ||
  99            x1 > x2  || x2 > x3  || x3 > x4              ||
 100            y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 )
 101         return FT_THROW( Invalid_Argument );
 102 
 103       driver->darken_params[0] = x1;
 104       driver->darken_params[1] = y1;
 105       driver->darken_params[2] = x2;
 106       driver->darken_params[3] = y2;
 107       driver->darken_params[4] = x3;
 108       driver->darken_params[5] = y3;
 109       driver->darken_params[6] = x4;
 110       driver->darken_params[7] = y4;
 111 
 112       return error;
 113     }
 114 
 115     else if ( !ft_strcmp( property_name, "hinting-engine" ) )
 116     {
 117 #if defined( CFF_CONFIG_OPTION_OLD_ENGINE ) || \
 118     defined( T1_CONFIG_OPTION_OLD_ENGINE  )
 119       const char*  module_name = module->clazz->module_name;
 120 #endif
 121 
 122 
 123 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
 124       if ( value_is_string )
 125       {
 126         const char*  s = (const char*)value;
 127 
 128 
 129         if ( !ft_strcmp( s, "adobe" ) )
 130           driver->hinting_engine = FT_HINTING_ADOBE;
 131 
 132 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 133         else if ( !ft_strcmp( module_name, "cff" ) &&
 134                   !ft_strcmp( s, "freetype" )      )
 135           driver->hinting_engine = FT_HINTING_FREETYPE;
 136 #endif
 137 
 138 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
 139         else if ( ( !ft_strcmp( module_name, "type1" ) ||
 140                     !ft_strcmp( module_name, "t1cid" ) ) &&
 141                   !ft_strcmp( s, "freetype" )            )
 142           driver->hinting_engine = FT_HINTING_FREETYPE;
 143 #endif
 144 
 145         else
 146           return FT_THROW( Invalid_Argument );
 147       }
 148       else
 149 #endif /* FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES */
 150       {
 151         FT_UInt*  hinting_engine = (FT_UInt*)value;
 152 
 153 
 154         if ( *hinting_engine == FT_HINTING_ADOBE
 155 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 156              || ( *hinting_engine == FT_HINTING_FREETYPE &&
 157                   !ft_strcmp( module_name, "cff" )       )
 158 #endif
 159 #ifdef T1_CONFIG_OPTION_OLD_ENGINE
 160              || ( *hinting_engine == FT_HINTING_FREETYPE &&
 161                   ( !ft_strcmp( module_name, "type1" ) ||
 162                     !ft_strcmp( module_name, "t1cid" ) ) )
 163 #endif
 164            )
 165           driver->hinting_engine = *hinting_engine;
 166         else
 167           error = FT_ERR( Unimplemented_Feature );
 168 
 169         return error;
 170       }
 171     }
 172 
 173     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
 174     {
 175 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
 176       if ( value_is_string )
 177       {
 178         const char*  s   = (const char*)value;
 179         long         nsd = ft_strtol( s, NULL, 10 );
 180 
 181 
 182         if ( !nsd )
 183           driver->no_stem_darkening = FALSE;
 184         else
 185           driver->no_stem_darkening = TRUE;
 186       }
 187       else
 188 #endif
 189       {
 190         FT_Bool*  no_stem_darkening = (FT_Bool*)value;
 191 
 192 
 193         driver->no_stem_darkening = *no_stem_darkening;
 194       }
 195 
 196       return error;
 197     }
 198 
 199     else if ( !ft_strcmp( property_name, "random-seed" ) )
 200     {
 201       FT_Int32  random_seed;
 202 
 203 
 204 #ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
 205       if ( value_is_string )
 206       {
 207         const char*  s = (const char*)value;
 208 
 209 
 210         random_seed = (FT_Int32)ft_strtol( s, NULL, 10 );
 211       }
 212       else
 213 #endif
 214         random_seed = *(FT_Int32*)value;
 215 
 216       if ( random_seed < 0 )
 217         random_seed = 0;
 218 
 219       driver->random_seed = random_seed;
 220 
 221       return error;
 222     }
 223 
 224     FT_TRACE0(( "ps_property_set: missing property `%s'\n",
 225                 property_name ));
 226     return FT_THROW( Missing_Property );
 227   }
 228 
 229 
 230   FT_BASE_CALLBACK_DEF( FT_Error )
 231   ps_property_get( FT_Module    module,         /* PS_Driver */
 232                    const char*  property_name,
 233                    void*        value )
 234   {
 235     FT_Error   error  = FT_Err_Ok;
 236     PS_Driver  driver = (PS_Driver)module;
 237 
 238 
 239     if ( !ft_strcmp( property_name, "darkening-parameters" ) )
 240     {
 241       FT_Int*  darken_params = driver->darken_params;
 242       FT_Int*  val           = (FT_Int*)value;
 243 
 244 
 245       val[0] = darken_params[0];
 246       val[1] = darken_params[1];
 247       val[2] = darken_params[2];
 248       val[3] = darken_params[3];
 249       val[4] = darken_params[4];
 250       val[5] = darken_params[5];
 251       val[6] = darken_params[6];
 252       val[7] = darken_params[7];
 253 
 254       return error;
 255     }
 256 
 257     else if ( !ft_strcmp( property_name, "hinting-engine" ) )
 258     {
 259       FT_UInt   hinting_engine    = driver->hinting_engine;
 260       FT_UInt*  val               = (FT_UInt*)value;
 261 
 262 
 263       *val = hinting_engine;
 264 
 265       return error;
 266     }
 267 
 268     else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
 269     {
 270       FT_Bool   no_stem_darkening = driver->no_stem_darkening;
 271       FT_Bool*  val               = (FT_Bool*)value;
 272 
 273 
 274       *val = no_stem_darkening;
 275 
 276       return error;
 277     }
 278 
 279     FT_TRACE0(( "ps_property_get: missing property `%s'\n",
 280                 property_name ));
 281     return FT_THROW( Missing_Property );
 282   }
 283 
 284 
 285 /* END */