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-2023 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 )
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_TRACE2(( "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 )
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_TRACE2(( "ps_property_get: missing property `%s'\n",
279 property_name ));
280 return FT_THROW( Missing_Property );
281 }
282
283
284/* END */
285