• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftmm.c                                                                 */
4 /*                                                                         */
5 /*    Multiple Master font support (body).                                 */
6 /*                                                                         */
7 /*  Copyright 1996-2017 by                                                 */
8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 /*                                                                         */
10 /*  This file is part of the FreeType project, and may only be used,       */
11 /*  modified, and distributed under the terms of the FreeType project      */
12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 /*  this file you indicate that you have read the license and              */
14 /*  understand and accept it fully.                                        */
15 /*                                                                         */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 
22 #include FT_MULTIPLE_MASTERS_H
23 #include FT_INTERNAL_OBJECTS_H
24 #include FT_SERVICE_MULTIPLE_MASTERS_H
25 #include FT_SERVICE_METRICS_VARIATIONS_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_mm
36 
37 
38   static FT_Error
ft_face_get_mm_service(FT_Face face,FT_Service_MultiMasters * aservice)39   ft_face_get_mm_service( FT_Face                   face,
40                           FT_Service_MultiMasters  *aservice )
41   {
42     FT_Error  error;
43 
44 
45     *aservice = NULL;
46 
47     if ( !face )
48       return FT_THROW( Invalid_Face_Handle );
49 
50     error = FT_ERR( Invalid_Argument );
51 
52     if ( FT_HAS_MULTIPLE_MASTERS( face ) )
53     {
54       FT_FACE_LOOKUP_SERVICE( face,
55                               *aservice,
56                               MULTI_MASTERS );
57 
58       if ( *aservice )
59         error = FT_Err_Ok;
60     }
61 
62     return error;
63   }
64 
65 
66   static FT_Error
ft_face_get_mvar_service(FT_Face face,FT_Service_MetricsVariations * aservice)67   ft_face_get_mvar_service( FT_Face                        face,
68                             FT_Service_MetricsVariations  *aservice )
69   {
70     FT_Error  error;
71 
72 
73     *aservice = NULL;
74 
75     if ( !face )
76       return FT_THROW( Invalid_Face_Handle );
77 
78     error = FT_ERR( Invalid_Argument );
79 
80     if ( FT_HAS_MULTIPLE_MASTERS( face ) )
81     {
82       FT_FACE_LOOKUP_SERVICE( face,
83                               *aservice,
84                               METRICS_VARIATIONS );
85 
86       if ( *aservice )
87         error = FT_Err_Ok;
88     }
89 
90     return error;
91   }
92 
93 
94   /* documentation is in ftmm.h */
95 
96   FT_EXPORT_DEF( FT_Error )
FT_Get_Multi_Master(FT_Face face,FT_Multi_Master * amaster)97   FT_Get_Multi_Master( FT_Face           face,
98                        FT_Multi_Master  *amaster )
99   {
100     FT_Error                 error;
101     FT_Service_MultiMasters  service;
102 
103 
104     /* check of `face' delayed to `ft_face_get_mm_service' */
105 
106     if ( !amaster )
107       return FT_THROW( Invalid_Argument );
108 
109     error = ft_face_get_mm_service( face, &service );
110     if ( !error )
111     {
112       error = FT_ERR( Invalid_Argument );
113       if ( service->get_mm )
114         error = service->get_mm( face, amaster );
115     }
116 
117     return error;
118   }
119 
120 
121   /* documentation is in ftmm.h */
122 
123   FT_EXPORT_DEF( FT_Error )
FT_Get_MM_Var(FT_Face face,FT_MM_Var ** amaster)124   FT_Get_MM_Var( FT_Face      face,
125                  FT_MM_Var*  *amaster )
126   {
127     FT_Error                 error;
128     FT_Service_MultiMasters  service;
129 
130 
131     /* check of `face' delayed to `ft_face_get_mm_service' */
132 
133     if ( !amaster )
134       return FT_THROW( Invalid_Argument );
135 
136     error = ft_face_get_mm_service( face, &service );
137     if ( !error )
138     {
139       error = FT_ERR( Invalid_Argument );
140       if ( service->get_mm_var )
141         error = service->get_mm_var( face, amaster );
142     }
143 
144     return error;
145   }
146 
147 
148   /* documentation is in ftmm.h */
149 
150   FT_EXPORT_DEF( FT_Error )
FT_Set_MM_Design_Coordinates(FT_Face face,FT_UInt num_coords,FT_Long * coords)151   FT_Set_MM_Design_Coordinates( FT_Face   face,
152                                 FT_UInt   num_coords,
153                                 FT_Long*  coords )
154   {
155     FT_Error                 error;
156     FT_Service_MultiMasters  service;
157 
158 
159     /* check of `face' delayed to `ft_face_get_mm_service' */
160 
161     if ( !coords )
162       return FT_THROW( Invalid_Argument );
163 
164     error = ft_face_get_mm_service( face, &service );
165     if ( !error )
166     {
167       error = FT_ERR( Invalid_Argument );
168       if ( service->set_mm_design )
169         error = service->set_mm_design( face, num_coords, coords );
170     }
171 
172     /* enforce recomputation of auto-hinting data */
173     if ( !error && face->autohint.finalizer )
174     {
175       face->autohint.finalizer( face->autohint.data );
176       face->autohint.data = NULL;
177     }
178 
179     return error;
180   }
181 
182 
183   /* documentation is in ftmm.h */
184 
185   FT_EXPORT_DEF( FT_Error )
FT_Set_Var_Design_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)186   FT_Set_Var_Design_Coordinates( FT_Face    face,
187                                  FT_UInt    num_coords,
188                                  FT_Fixed*  coords )
189   {
190     FT_Error                      error;
191     FT_Service_MultiMasters       service_mm;
192     FT_Service_MetricsVariations  service_mvar;
193 
194 
195     /* check of `face' delayed to `ft_face_get_mm_service' */
196 
197     if ( !coords )
198       return FT_THROW( Invalid_Argument );
199 
200     error = ft_face_get_mm_service( face, &service_mm );
201     if ( !error )
202     {
203       error = FT_ERR( Invalid_Argument );
204       if ( service_mm->set_var_design )
205         error = service_mm->set_var_design( face, num_coords, coords );
206     }
207 
208     if ( !error )
209       error = ft_face_get_mvar_service( face, &service_mvar );
210 
211     if ( !error )
212     {
213       if ( service_mvar->metrics_adjust )
214         service_mvar->metrics_adjust( face );
215     }
216 
217     /* enforce recomputation of auto-hinting data */
218     if ( !error && face->autohint.finalizer )
219     {
220       face->autohint.finalizer( face->autohint.data );
221       face->autohint.data = NULL;
222     }
223 
224     return error;
225   }
226 
227 
228   /* documentation is in ftmm.h */
229 
230   FT_EXPORT_DEF( FT_Error )
FT_Get_Var_Design_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)231   FT_Get_Var_Design_Coordinates( FT_Face    face,
232                                  FT_UInt    num_coords,
233                                  FT_Fixed*  coords )
234   {
235     FT_Error                 error;
236     FT_Service_MultiMasters  service;
237 
238 
239     /* check of `face' delayed to `ft_face_get_mm_service' */
240 
241     if ( !coords )
242       return FT_THROW( Invalid_Argument );
243 
244     error = ft_face_get_mm_service( face, &service );
245     if ( !error )
246     {
247       error = FT_ERR( Invalid_Argument );
248       if ( service->get_var_design )
249         error = service->get_var_design( face, num_coords, coords );
250     }
251 
252     return error;
253   }
254 
255 
256   /* documentation is in ftmm.h */
257 
258   FT_EXPORT_DEF( FT_Error )
FT_Set_MM_Blend_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)259   FT_Set_MM_Blend_Coordinates( FT_Face    face,
260                                FT_UInt    num_coords,
261                                FT_Fixed*  coords )
262   {
263     FT_Error                      error;
264     FT_Service_MultiMasters       service_mm;
265     FT_Service_MetricsVariations  service_mvar;
266 
267 
268     /* check of `face' delayed to `ft_face_get_mm_service' */
269 
270     if ( !coords )
271       return FT_THROW( Invalid_Argument );
272 
273     error = ft_face_get_mm_service( face, &service_mm );
274     if ( !error )
275     {
276       error = FT_ERR( Invalid_Argument );
277       if ( service_mm->set_mm_blend )
278         error = service_mm->set_mm_blend( face, num_coords, coords );
279     }
280 
281     if ( !error )
282       error = ft_face_get_mvar_service( face, &service_mvar );
283 
284     if ( !error )
285     {
286       if ( service_mvar->metrics_adjust )
287         service_mvar->metrics_adjust( face );
288     }
289 
290     /* enforce recomputation of auto-hinting data */
291     if ( !error && face->autohint.finalizer )
292     {
293       face->autohint.finalizer( face->autohint.data );
294       face->autohint.data = NULL;
295     }
296 
297     return error;
298   }
299 
300 
301   /* documentation is in ftmm.h */
302 
303   /* This is exactly the same as the previous function.  It exists for */
304   /* orthogonality.                                                    */
305 
306   FT_EXPORT_DEF( FT_Error )
FT_Set_Var_Blend_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)307   FT_Set_Var_Blend_Coordinates( FT_Face    face,
308                                 FT_UInt    num_coords,
309                                 FT_Fixed*  coords )
310   {
311     FT_Error                      error;
312     FT_Service_MultiMasters       service_mm;
313     FT_Service_MetricsVariations  service_mvar;
314 
315 
316     /* check of `face' delayed to `ft_face_get_mm_service' */
317 
318     if ( !coords )
319       return FT_THROW( Invalid_Argument );
320 
321     error = ft_face_get_mm_service( face, &service_mm );
322     if ( !error )
323     {
324       error = FT_ERR( Invalid_Argument );
325       if ( service_mm->set_mm_blend )
326         error = service_mm->set_mm_blend( face, num_coords, coords );
327     }
328 
329     if ( !error )
330       error = ft_face_get_mvar_service( face, &service_mvar );
331 
332     if ( !error )
333     {
334       if ( service_mvar->metrics_adjust )
335         service_mvar->metrics_adjust( face );
336     }
337 
338     /* enforce recomputation of auto-hinting data */
339     if ( !error && face->autohint.finalizer )
340     {
341       face->autohint.finalizer( face->autohint.data );
342       face->autohint.data = NULL;
343     }
344 
345     return error;
346   }
347 
348 
349   /* documentation is in ftmm.h */
350 
351   FT_EXPORT_DEF( FT_Error )
FT_Get_MM_Blend_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)352   FT_Get_MM_Blend_Coordinates( FT_Face    face,
353                                FT_UInt    num_coords,
354                                FT_Fixed*  coords )
355   {
356     FT_Error                 error;
357     FT_Service_MultiMasters  service;
358 
359 
360     /* check of `face' delayed to `ft_face_get_mm_service' */
361 
362     if ( !coords )
363       return FT_THROW( Invalid_Argument );
364 
365     error = ft_face_get_mm_service( face, &service );
366     if ( !error )
367     {
368       error = FT_ERR( Invalid_Argument );
369       if ( service->get_mm_blend )
370         error = service->get_mm_blend( face, num_coords, coords );
371     }
372 
373     return error;
374   }
375 
376 
377   /* documentation is in ftmm.h */
378 
379   /* This is exactly the same as the previous function.  It exists for */
380   /* orthogonality.                                                    */
381 
382   FT_EXPORT_DEF( FT_Error )
FT_Get_Var_Blend_Coordinates(FT_Face face,FT_UInt num_coords,FT_Fixed * coords)383   FT_Get_Var_Blend_Coordinates( FT_Face    face,
384                                 FT_UInt    num_coords,
385                                 FT_Fixed*  coords )
386   {
387     FT_Error                 error;
388     FT_Service_MultiMasters  service;
389 
390 
391     /* check of `face' delayed to `ft_face_get_mm_service' */
392 
393     if ( !coords )
394       return FT_THROW( Invalid_Argument );
395 
396     error = ft_face_get_mm_service( face, &service );
397     if ( !error )
398     {
399       error = FT_ERR( Invalid_Argument );
400       if ( service->get_mm_blend )
401         error = service->get_mm_blend( face, num_coords, coords );
402     }
403 
404     return error;
405   }
406 
407 
408 /* END */
409