:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / subsys / win32k / freetype / src / type1 / t1objs.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  t1objs.c                                                               */
4 /*                                                                         */
5 /*    Type 1 objects manager (body).                                       */
6 /*                                                                         */
7 /*  Copyright 1996-2000 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 <freetype/internal/ftdebug.h>
20 #include <freetype/internal/ftstream.h>
21
22
23 #ifdef FT_FLAT_COMPILE
24
25 #include "t1gload.h"
26 #include "t1load.h"
27 #include "t1afm.h"
28
29 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
30 #include "t1hinter.h"
31 #endif
32
33 #else /* FT_FLAT_COMPILE */
34
35 #include <freetype/src/type1/t1gload.h>
36 #include <freetype/src/type1/t1load.h>
37 #include <freetype/src/type1/t1afm.h>
38
39 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
40 #include <freetype/src/type1/t1hinter.h>
41 #endif
42
43 #endif /* FT_FLAT_COMPILE */
44
45
46 #include <freetype/internal/psnames.h>
47
48
49   /*************************************************************************/
50   /*                                                                       */
51   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
52   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
53   /* messages during execution.                                            */
54   /*                                                                       */
55 #undef  FT_COMPONENT
56 #define FT_COMPONENT  trace_t1objs
57
58
59   /*************************************************************************/
60   /*                                                                       */
61   /*                           SIZE  FUNCTIONS                             */
62   /*                                                                       */
63   /*************************************************************************/
64
65
66   /*************************************************************************/
67   /*                                                                       */
68   /* <Function>                                                            */
69   /*    T1_Done_Size                                                       */
70   /*                                                                       */
71   /* <Description>                                                         */
72   /*    The Type 1 size object destructor.  Used to discard a given size   */
73   /*    object.                                                            */
74   /*                                                                       */
75   /* <Input>                                                               */
76   /*    size :: A handle to the target size object.                        */
77   /*                                                                       */
78   LOCAL_FUNC
79   void  T1_Done_Size( T1_Size  size )
80   {
81     if ( size )
82     {
83
84 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
85       T1_Done_Size_Hinter( size );
86 #endif
87
88       size->valid = 0;
89     }
90   }
91
92
93   /*************************************************************************/
94   /*                                                                       */
95   /* <Function>                                                            */
96   /*    T1_Init_Size                                                       */
97   /*                                                                       */
98   /* <Description>                                                         */
99   /*    The size object initializer.                                       */
100   /*                                                                       */
101   /* <Input>                                                               */
102   /*    size :: A handle to the target size object.                        */
103   /*                                                                       */
104   /* <Return>                                                              */
105   /*    FreeTrue error code.  0 means success.                             */
106   /*                                                                       */
107   LOCAL_DEF
108   FT_Error  T1_Init_Size( T1_Size  size )
109   {
110     FT_Error  error;
111
112
113     size->valid = 0;
114
115 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
116     error = T1_New_Size_Hinter( size );
117
118     return error;
119 #else
120
121     FT_UNUSED( error );
122
123     return T1_Err_Ok;
124
125 #endif
126   }
127
128
129   /*************************************************************************/
130   /*                                                                       */
131   /* <Function>                                                            */
132   /*    T1_Reset_Size                                                      */
133   /*                                                                       */
134   /* <Description>                                                         */
135   /*    Resets an instance to a new pointsize/transform.  This function is */
136   /*    in charge of resetting the blue zones,a s well as the stem snap    */
137   /*    tables for a given size.                                           */
138   /*                                                                       */
139   /* <Input>                                                               */
140   /*    size :: The target size object.                                    */
141   /*                                                                       */
142   /* <Output>                                                              */
143   /*    FreeType error code.  0 means success.                             */
144   /*                                                                       */
145   LOCAL_FUNC
146   FT_Error  T1_Reset_Size( T1_Size  size )
147   {
148     /* recompute ascender, descender, etc. */
149     T1_Face           face    = (T1_Face)size->root.face;
150     FT_Size_Metrics*  metrics = &size->root.metrics;
151
152
153     if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
154       return FT_Err_Invalid_Argument;
155
156     /* Compute root ascender, descender, test height, and max_advance */
157     metrics->ascender    = ( FT_MulFix( face->root.ascender,
158                                         metrics->y_scale ) + 32 ) & -64;
159     metrics->descender   = ( FT_MulFix( face->root.descender,
160                                         metrics->y_scale ) + 32 ) & -64;
161     metrics->height      = ( FT_MulFix( face->root.height,
162                                         metrics->y_scale ) + 32 ) & -64;
163     metrics->max_advance = ( FT_MulFix( face->root.max_advance_width,
164                                         metrics->x_scale ) + 32 ) & -64;
165
166 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
167     return T1_Reset_Size_Hinter( size );
168 #else
169     return 0;
170 #endif
171   }
172
173
174   /*************************************************************************/
175   /*                                                                       */
176   /*                            FACE  FUNCTIONS                            */
177   /*                                                                       */
178   /*************************************************************************/
179
180
181   /*************************************************************************/
182   /*                                                                       */
183   /* <Function>                                                            */
184   /*    T1_Done_Face                                                       */
185   /*                                                                       */
186   /* <Description>                                                         */
187   /*    The face object destructor.                                        */
188   /*                                                                       */
189   /* <Input>                                                               */
190   /*    face :: A typeless pointer to the face object to destroy.          */
191   /*                                                                       */
192   LOCAL_FUNC
193   void  T1_Done_Face( T1_Face  face )
194   {
195     FT_Memory  memory;
196     T1_Font*   type1 = &face->type1;
197
198
199     if ( face )
200     {
201       memory = face->root.memory;
202
203       /* release font info strings */
204       {
205         T1_FontInfo*  info = &type1->font_info;
206
207
208         FREE( info->version );
209         FREE( info->notice );
210         FREE( info->full_name );
211         FREE( info->family_name );
212         FREE( info->weight );
213       }
214
215       /* release top dictionary */
216       FREE( type1->charstrings_len );
217       FREE( type1->charstrings );
218       FREE( type1->glyph_names );
219
220       FREE( type1->subrs );
221       FREE( type1->subrs_len );
222
223       FREE( type1->subrs_block );
224       FREE( type1->charstrings_block );
225       FREE( type1->glyph_names_block );
226
227       FREE( type1->encoding.char_index );
228       FREE( type1->font_name );
229
230 #ifndef T1_CONFIG_OPTION_NO_AFM
231       /* release afm data if present */
232       if ( face->afm_data )
233         T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
234 #endif
235
236       /* release unicode map, if any */
237       FREE( face->unicode_map.maps );
238       face->unicode_map.num_maps = 0;
239
240       face->root.family_name = 0;
241       face->root.style_name  = 0;
242     }
243   }
244
245
246   /*************************************************************************/
247   /*                                                                       */
248   /* <Function>                                                            */
249   /*    T1_Init_Face                                                       */
250   /*                                                                       */
251   /* <Description>                                                         */
252   /*    The face object constructor.                                       */
253   /*                                                                       */
254   /* <Input>                                                               */
255   /*    stream     ::  input stream where to load font data.               */
256   /*                                                                       */
257   /*    face_index :: The index of the font face in the resource.          */
258   /*                                                                       */
259   /*    num_params :: Number of additional generic parameters.  Ignored.   */
260   /*                                                                       */
261   /*    params     :: Additional generic parameters.  Ignored.             */
262   /*                                                                       */
263   /* <InOut>                                                               */
264   /*    face       :: The face record to build.                            */
265   /*                                                                       */
266   /* <Return>                                                              */
267   /*    FreeType error code.  0 means success.                             */
268   /*                                                                       */
269   LOCAL_FUNC
270   FT_Error  T1_Init_Face( FT_Stream      stream,
271                           T1_Face        face,
272                           FT_Int         face_index,
273                           FT_Int         num_params,
274                           FT_Parameter*  params )
275   {
276     T1_Tokenizer        tokenizer;
277     FT_Error            error;
278     PSNames_Interface*  psnames;
279
280     FT_UNUSED( num_params );
281     FT_UNUSED( params );
282     FT_UNUSED( face_index );
283     FT_UNUSED( face );
284
285
286     face->root.num_faces = 1;
287
288     psnames = (PSNames_Interface*)face->psnames;
289     if ( !psnames )
290     {
291       psnames = (PSNames_Interface*)
292                  FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
293                                           "psnames" );
294
295       face->psnames = psnames;
296     }
297
298     /* open the tokenizer, this will also check the font format */
299     error = New_Tokenizer( stream, &tokenizer );
300     if ( error )
301       goto Fail;
302
303     /* if we just wanted to check the format, leave successfully now */
304     if ( face_index < 0 )
305       goto Leave;
306
307     /* check the face index */
308     if ( face_index != 0 )
309     {
310       FT_ERROR(( "T1_Init_Face: invalid face index\n" ));
311       error = T1_Err_Invalid_Argument;
312       goto Leave;
313     }
314
315     /* Now, load the font program into the face object */
316     {
317       T1_Parser  parser;
318
319
320       Init_T1_Parser( &parser, face, tokenizer );
321       error = Parse_T1_FontProgram( &parser );
322       if ( error )
323         goto Leave;
324
325       /* Init the face object fields */
326       /* Now set up root face fields */
327       {
328         FT_Face   root  = (FT_Face)&face->root;
329         T1_Font*  type1 = &face->type1;
330
331
332         root->num_glyphs   = type1->num_glyphs;
333         root->num_charmaps = 1;
334
335         root->face_index = face_index;
336         root->face_flags = FT_FACE_FLAG_SCALABLE;
337
338         root->face_flags |= FT_FACE_FLAG_HORIZONTAL;
339
340         root->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
341         
342         if ( type1->font_info.is_fixed_pitch )
343           root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
344
345         /* XXX: TODO -- add kerning with .afm support */
346
347         /* get style name - be careful, some broken fonts only */
348         /* have a `/FontName' dictionary entry!                */
349         root->family_name = type1->font_info.family_name;
350         if ( root->family_name )
351         {
352           char*  full   = type1->font_info.full_name;
353           char*  family = root->family_name;
354
355
356           while ( *family && *full == *family )
357           {
358             family++;
359             full++;
360           }
361
362           root->style_name = ( *full == ' ' ? full + 1
363                                             : (char *)"Regular" );
364         }
365         else
366         {
367           /* do we have a `/FontName'? */
368           if (type1->font_name)
369           {
370             root->family_name = type1->font_name;
371             root->style_name  = "Regular";
372           }
373         }
374
375         /* no embedded bitmap support */
376         root->num_fixed_sizes = 0;
377         root->available_sizes = 0;
378
379         root->bbox         = type1->font_bbox;
380         root->units_per_EM = 1000;
381         root->ascender     =  (FT_Short)type1->font_bbox.yMax;
382         root->descender    = -(FT_Short)type1->font_bbox.yMin;
383         root->height       = ( ( root->ascender + root->descender) * 12 )
384                              / 10;
385
386         /* now compute the maximum advance width */
387
388         root->max_advance_width = type1->private_dict.standard_width[0];
389
390         /* compute max advance width for proportional fonts */
391         if ( !type1->font_info.is_fixed_pitch )
392         {
393           FT_Int  max_advance;
394
395
396           error = T1_Compute_Max_Advance( face, &max_advance );
397
398           /* in case of error, keep the standard width */
399           if ( !error )
400             root->max_advance_width = max_advance;
401           else
402             error = 0;   /* clear error */
403         }
404
405         root->max_advance_height = root->height;
406
407         root->underline_position  = type1->font_info.underline_position;
408         root->underline_thickness = type1->font_info.underline_thickness;
409
410         root->max_points   = 0;
411         root->max_contours = 0;
412       }
413     }
414
415     /* charmap support - synthetize unicode charmap when possible */
416     {
417       FT_Face     root    = &face->root;
418       FT_CharMap  charmap = face->charmaprecs;
419
420
421       /* synthesize a Unicode charmap if there is support in the `PSNames' */
422       /* module..                                                          */
423       if ( face->psnames )
424       {
425         PSNames_Interface*  psnames = (PSNames_Interface*)face->psnames;
426
427
428         if ( psnames->unicode_value )
429         {
430           error = psnames->build_unicodes(
431                     root->memory,
432                     face->type1.num_glyphs,
433                     (const char**)face->type1.glyph_names,
434                     &face->unicode_map );
435           if ( !error )
436           {
437             root->charmap        = charmap;
438             charmap->face        = (FT_Face)face;
439             charmap->encoding    = ft_encoding_unicode;
440             charmap->platform_id = 3;
441             charmap->encoding_id = 1;
442             charmap++;
443           }
444
445           /* simply clear the error in case of failure (which really) */
446           /* means that out of memory or no unicode glyph names       */
447           error = 0;
448         }
449       }
450
451       /* now, support either the standard, expert, or custom encodings */
452       charmap->face        = (FT_Face)face;
453       charmap->platform_id = 7;  /* a new platform id for Adobe fonts ?? */
454
455       switch ( face->type1.encoding_type )
456       {
457       case t1_encoding_standard:
458         charmap->encoding    = ft_encoding_adobe_standard;
459         charmap->encoding_id = 0;
460         break;
461
462       case t1_encoding_expert:
463         charmap->encoding    = ft_encoding_adobe_expert;
464         charmap->encoding_id = 1;
465         break;
466
467       default:
468         charmap->encoding    = ft_encoding_adobe_custom;
469         charmap->encoding_id = 2;
470         break;
471       }
472
473       root->charmaps     = face->charmaps;
474       root->num_charmaps = charmap - face->charmaprecs + 1;
475       face->charmaps[0]  = &face->charmaprecs[0];
476       face->charmaps[1]  = &face->charmaprecs[1];
477     }
478
479   Leave:
480     Done_Tokenizer( tokenizer );
481
482   Fail:
483     return error;
484   }
485
486
487   /*************************************************************************/
488   /*                                                                       */
489   /* <Function>                                                            */
490   /*    T1_Done_GlyphSlot                                                  */
491   /*                                                                       */
492   /* <Description>                                                         */
493   /*    The glyph slot object destructor.                                  */
494   /*                                                                       */
495   /* <Input>                                                               */
496   /*    glyph :: The glyph slot handle to destroy.                         */
497   /*                                                                       */
498   LOCAL_FUNC
499   void  T1_Done_GlyphSlot( T1_GlyphSlot  glyph )
500   {
501 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
502
503     T1_Done_Glyph_Hinter( glyph );
504
505 #else
506
507     FT_UNUSED( glyph );
508
509 #endif
510   }
511
512
513   /*************************************************************************/
514   /*                                                                       */
515   /* <Function>                                                            */
516   /*    T1_Init_GlyphSlot                                                  */
517   /*                                                                       */
518   /* <Description>                                                         */
519   /*    The glyph slot object constructor.                                 */
520   /*                                                                       */
521   /* <Input>                                                               */
522   /*    glyph :: The glyph slot handle to initialize.                      */
523   /*                                                                       */
524   LOCAL_FUNC
525   FT_Error  T1_Init_GlyphSlot( T1_GlyphSlot  glyph )
526   {
527     FT_Error    error = FT_Err_Ok;
528
529
530 #ifndef T1_CONFIG_OPTION_DISABLE_HINTER
531
532     error = T1_New_Glyph_Hinter( glyph );
533
534 #else
535
536     FT_UNUSED( glyph );
537
538 #endif
539
540     return error;
541   }
542
543
544 /* END */