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 | |