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