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 )
ps_property_set(FT_Module module,const char * property_name,const void * value,FT_Bool value_is_string)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 )
ps_property_get(FT_Module module,const char * property_name,void * value)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 */
286