Initialize Tizen 2.3
[framework/graphics/freetype.git] / src / type42 / t42objs.c
1 /***************************************************************************/
2 /*                                                                         */
3 /*  t42objs.c                                                              */
4 /*                                                                         */
5 /*    Type 42 objects manager (body).                                      */
6 /*                                                                         */
7 /*  Copyright 2002-2009, 2011                                              */
8 /*  by Roberto Alameda.                                                    */
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 "t42objs.h"
20 #include "t42parse.h"
21 #include "t42error.h"
22 #include FT_INTERNAL_DEBUG_H
23 #include FT_LIST_H
24 #include FT_TRUETYPE_IDS_H
25
26
27 #undef  FT_COMPONENT
28 #define FT_COMPONENT  trace_t42
29
30
31   static FT_Error
32   T42_Open_Face( T42_Face  face )
33   {
34     T42_LoaderRec  loader;
35     T42_Parser     parser;
36     T1_Font        type1 = &face->type1;
37     FT_Memory      memory = face->root.memory;
38     FT_Error       error;
39
40     PSAux_Service  psaux  = (PSAux_Service)face->psaux;
41
42
43     t42_loader_init( &loader, face );
44
45     parser = &loader.parser;
46
47     if ( FT_ALLOC( face->ttf_data, 12 ) )
48       goto Exit;
49
50     error = t42_parser_init( parser,
51                              face->root.stream,
52                              memory,
53                              psaux);
54     if ( error )
55       goto Exit;
56
57     error = t42_parse_dict( face, &loader,
58                             parser->base_dict, parser->base_len );
59     if ( error )
60       goto Exit;
61
62     if ( type1->font_type != 42 )
63     {
64       FT_ERROR(( "T42_Open_Face: cannot handle FontType %d\n",
65                  type1->font_type ));
66       error = T42_Err_Unknown_File_Format;
67       goto Exit;
68     }
69
70     /* now, propagate the charstrings and glyphnames tables */
71     /* to the Type1 data                                    */
72     type1->num_glyphs = loader.num_glyphs;
73
74     if ( !loader.charstrings.init )
75     {
76       FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" ));
77       error = T42_Err_Invalid_File_Format;
78     }
79
80     loader.charstrings.init  = 0;
81     type1->charstrings_block = loader.charstrings.block;
82     type1->charstrings       = loader.charstrings.elements;
83     type1->charstrings_len   = loader.charstrings.lengths;
84
85     /* we copy the glyph names `block' and `elements' fields; */
86     /* the `lengths' field must be released later             */
87     type1->glyph_names_block    = loader.glyph_names.block;
88     type1->glyph_names          = (FT_String**)loader.glyph_names.elements;
89     loader.glyph_names.block    = 0;
90     loader.glyph_names.elements = 0;
91
92     /* we must now build type1.encoding when we have a custom array */
93     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
94     {
95       FT_Int    charcode, idx, min_char, max_char;
96       FT_Byte*  char_name;
97       FT_Byte*  glyph_name;
98
99
100       /* OK, we do the following: for each element in the encoding   */
101       /* table, look up the index of the glyph having the same name  */
102       /* as defined in the CharStrings array.                        */
103       /* The index is then stored in type1.encoding.char_index, and  */
104       /* the name in type1.encoding.char_name                        */
105
106       min_char = 0;
107       max_char = 0;
108
109       charcode = 0;
110       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
111       {
112         type1->encoding.char_index[charcode] = 0;
113         type1->encoding.char_name [charcode] = (char *)".notdef";
114
115         char_name = loader.encoding_table.elements[charcode];
116         if ( char_name )
117           for ( idx = 0; idx < type1->num_glyphs; idx++ )
118           {
119             glyph_name = (FT_Byte*)type1->glyph_names[idx];
120             if ( ft_strcmp( (const char*)char_name,
121                             (const char*)glyph_name ) == 0 )
122             {
123               type1->encoding.char_index[charcode] = (FT_UShort)idx;
124               type1->encoding.char_name [charcode] = (char*)glyph_name;
125
126               /* Change min/max encoded char only if glyph name is */
127               /* not /.notdef                                      */
128               if ( ft_strcmp( (const char*)".notdef",
129                               (const char*)glyph_name ) != 0 )
130               {
131                 if ( charcode < min_char )
132                   min_char = charcode;
133                 if ( charcode >= max_char )
134                   max_char = charcode + 1;
135               }
136               break;
137             }
138           }
139       }
140
141       type1->encoding.code_first = min_char;
142       type1->encoding.code_last  = max_char;
143       type1->encoding.num_chars  = loader.num_chars;
144     }
145
146   Exit:
147     t42_loader_done( &loader );
148     return error;
149   }
150
151
152   /***************** Driver Functions *************/
153
154
155   FT_LOCAL_DEF( FT_Error )
156   T42_Face_Init( FT_Stream      stream,
157                  FT_Face        t42face,       /* T42_Face */
158                  FT_Int         face_index,
159                  FT_Int         num_params,
160                  FT_Parameter*  params )
161   {
162     T42_Face            face  = (T42_Face)t42face;
163     FT_Error            error;
164     FT_Service_PsCMaps  psnames;
165     PSAux_Service       psaux;
166     FT_Face             root  = (FT_Face)&face->root;
167     T1_Font             type1 = &face->type1;
168     PS_FontInfo         info  = &type1->font_info;
169
170     FT_UNUSED( num_params );
171     FT_UNUSED( params );
172     FT_UNUSED( face_index );
173     FT_UNUSED( stream );
174
175
176     face->ttf_face       = NULL;
177     face->root.num_faces = 1;
178
179     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
180     face->psnames = psnames;
181
182     face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
183                                            "psaux" );
184     psaux = (PSAux_Service)face->psaux;
185     if ( !psaux )
186     {
187       FT_ERROR(( "T42_Face_Init: cannot access `psaux' module\n" ));
188       error = T42_Err_Missing_Module;
189       goto Exit;
190     }
191
192     FT_TRACE2(( "Type 42 driver\n" ));
193
194     /* open the tokenizer, this will also check the font format */
195     error = T42_Open_Face( face );
196     if ( error )
197       goto Exit;
198
199     /* if we just wanted to check the format, leave successfully now */
200     if ( face_index < 0 )
201       goto Exit;
202
203     /* check the face index */
204     if ( face_index > 0 )
205     {
206       FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
207       error = T42_Err_Invalid_Argument;
208       goto Exit;
209     }
210
211     /* Now load the font program into the face object */
212
213     /* Init the face object fields */
214     /* Now set up root face fields */
215
216     root->num_glyphs   = type1->num_glyphs;
217     root->num_charmaps = 0;
218     root->face_index   = 0;
219
220     root->face_flags = FT_FACE_FLAG_SCALABLE    |
221                        FT_FACE_FLAG_HORIZONTAL  |
222                        FT_FACE_FLAG_GLYPH_NAMES;
223
224     if ( info->is_fixed_pitch )
225       root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
226
227     /* We only set this flag if we have the patented bytecode interpreter. */
228     /* There are no known `tricky' Type42 fonts that could be loaded with  */
229     /* the unpatented interpreter.                                         */
230 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
231     root->face_flags |= FT_FACE_FLAG_HINTER;
232 #endif
233
234     /* XXX: TODO -- add kerning with .afm support */
235
236     /* get style name -- be careful, some broken fonts only */
237     /* have a `/FontName' dictionary entry!                 */
238     root->family_name = info->family_name;
239     /* assume "Regular" style if we don't know better */
240     root->style_name = (char *)"Regular";
241     if ( root->family_name )
242     {
243       char*  full   = info->full_name;
244       char*  family = root->family_name;
245
246
247       if ( full )
248       {
249         while ( *full )
250         {
251           if ( *full == *family )
252           {
253             family++;
254             full++;
255           }
256           else
257           {
258             if ( *full == ' ' || *full == '-' )
259               full++;
260             else if ( *family == ' ' || *family == '-' )
261               family++;
262             else
263             {
264               if ( !*family )
265                 root->style_name = full;
266               break;
267             }
268           }
269         }
270       }
271     }
272     else
273     {
274       /* do we have a `/FontName'? */
275       if ( type1->font_name )
276         root->family_name = type1->font_name;
277     }
278
279     /* no embedded bitmap support */
280     root->num_fixed_sizes = 0;
281     root->available_sizes = 0;
282
283     /* Load the TTF font embedded in the T42 font */
284     {
285       FT_Open_Args  args;
286
287
288       args.flags       = FT_OPEN_MEMORY;
289       args.memory_base = face->ttf_data;
290       args.memory_size = face->ttf_size;
291
292       if ( num_params )
293       {
294         args.flags     |= FT_OPEN_PARAMS;
295         args.num_params = num_params;
296         args.params     = params;
297       }
298
299       error = FT_Open_Face( FT_FACE_LIBRARY( face ),
300                             &args, 0, &face->ttf_face );
301     }
302
303     if ( error )
304       goto Exit;
305
306     FT_Done_Size( face->ttf_face->size );
307
308     /* Ignore info in FontInfo dictionary and use the info from the  */
309     /* loaded TTF font.  The PostScript interpreter also ignores it. */
310     root->bbox         = face->ttf_face->bbox;
311     root->units_per_EM = face->ttf_face->units_per_EM;
312
313     root->ascender  = face->ttf_face->ascender;
314     root->descender = face->ttf_face->descender;
315     root->height    = face->ttf_face->height;
316
317     root->max_advance_width  = face->ttf_face->max_advance_width;
318     root->max_advance_height = face->ttf_face->max_advance_height;
319
320     root->underline_position  = (FT_Short)info->underline_position;
321     root->underline_thickness = (FT_Short)info->underline_thickness;
322
323     /* compute style flags */
324     root->style_flags = 0;
325     if ( info->italic_angle )
326       root->style_flags |= FT_STYLE_FLAG_ITALIC;
327
328     if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
329       root->style_flags |= FT_STYLE_FLAG_BOLD;
330
331     if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
332       root->face_flags |= FT_FACE_FLAG_VERTICAL;
333
334     {
335       if ( psnames )
336       {
337         FT_CharMapRec    charmap;
338         T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
339         FT_CMap_Class    clazz;
340
341
342         charmap.face = root;
343
344         /* first of all, try to synthesize a Unicode charmap */
345         charmap.platform_id = TT_PLATFORM_MICROSOFT;
346         charmap.encoding_id = TT_MS_ID_UNICODE_CS;
347         charmap.encoding    = FT_ENCODING_UNICODE;
348
349         error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
350         if ( error && FT_Err_No_Unicode_Glyph_Name != error )
351           goto Exit;
352         error = FT_Err_Ok;
353
354         /* now, generate an Adobe Standard encoding when appropriate */
355         charmap.platform_id = TT_PLATFORM_ADOBE;
356         clazz               = NULL;
357
358         switch ( type1->encoding_type )
359         {
360         case T1_ENCODING_TYPE_STANDARD:
361           charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
362           charmap.encoding_id = TT_ADOBE_ID_STANDARD;
363           clazz               = cmap_classes->standard;
364           break;
365
366         case T1_ENCODING_TYPE_EXPERT:
367           charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
368           charmap.encoding_id = TT_ADOBE_ID_EXPERT;
369           clazz               = cmap_classes->expert;
370           break;
371
372         case T1_ENCODING_TYPE_ARRAY:
373           charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
374           charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
375           clazz               = cmap_classes->custom;
376           break;
377
378         case T1_ENCODING_TYPE_ISOLATIN1:
379           charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
380           charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
381           clazz               = cmap_classes->unicode;
382           break;
383
384         default:
385           ;
386         }
387
388         if ( clazz )
389           error = FT_CMap_New( clazz, NULL, &charmap, NULL );
390
391 #if 0
392         /* Select default charmap */
393         if ( root->num_charmaps )
394           root->charmap = root->charmaps[0];
395 #endif
396       }
397     }
398   Exit:
399     return error;
400   }
401
402
403   FT_LOCAL_DEF( void )
404   T42_Face_Done( FT_Face  t42face )
405   {
406     T42_Face     face = (T42_Face)t42face;
407     T1_Font      type1;
408     PS_FontInfo  info;
409     FT_Memory    memory;
410
411
412     if ( !face )
413       return;
414
415     type1  = &face->type1;
416     info   = &type1->font_info;
417     memory = face->root.memory;
418
419     /* delete internal ttf face prior to freeing face->ttf_data */
420     if ( face->ttf_face )
421       FT_Done_Face( face->ttf_face );
422
423     /* release font info strings */
424     FT_FREE( info->version );
425     FT_FREE( info->notice );
426     FT_FREE( info->full_name );
427     FT_FREE( info->family_name );
428     FT_FREE( info->weight );
429
430     /* release top dictionary */
431     FT_FREE( type1->charstrings_len );
432     FT_FREE( type1->charstrings );
433     FT_FREE( type1->glyph_names );
434
435     FT_FREE( type1->charstrings_block );
436     FT_FREE( type1->glyph_names_block );
437
438     FT_FREE( type1->encoding.char_index );
439     FT_FREE( type1->encoding.char_name );
440     FT_FREE( type1->font_name );
441
442     FT_FREE( face->ttf_data );
443
444 #if 0
445     /* release afm data if present */
446     if ( face->afm_data )
447       T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
448 #endif
449
450     /* release unicode map, if any */
451     FT_FREE( face->unicode_map.maps );
452     face->unicode_map.num_maps = 0;
453
454     face->root.family_name = 0;
455     face->root.style_name  = 0;
456   }
457
458
459   /*************************************************************************/
460   /*                                                                       */
461   /* <Function>                                                            */
462   /*    T42_Driver_Init                                                    */
463   /*                                                                       */
464   /* <Description>                                                         */
465   /*    Initializes a given Type 42 driver object.                         */
466   /*                                                                       */
467   /* <Input>                                                               */
468   /*    driver :: A handle to the target driver object.                    */
469   /*                                                                       */
470   /* <Return>                                                              */
471   /*    FreeType error code.  0 means success.                             */
472   /*                                                                       */
473   FT_LOCAL_DEF( FT_Error )
474   T42_Driver_Init( FT_Module  module )        /* T42_Driver */
475   {
476     T42_Driver  driver = (T42_Driver)module;
477     FT_Module   ttmodule;
478
479
480     ttmodule = FT_Get_Module( module->library, "truetype" );
481     if ( !ttmodule )
482     {
483       FT_ERROR(( "T42_Driver_Init: cannot access `truetype' module\n" ));
484       return T42_Err_Missing_Module;
485     }
486
487     driver->ttclazz = (FT_Driver_Class)ttmodule->clazz;
488
489     return T42_Err_Ok;
490   }
491
492
493   FT_LOCAL_DEF( void )
494   T42_Driver_Done( FT_Module  module )
495   {
496     FT_UNUSED( module );
497   }
498
499
500   FT_LOCAL_DEF( FT_Error )
501   T42_Size_Init( FT_Size  size )         /* T42_Size */
502   {
503     T42_Size  t42size = (T42_Size)size;
504     FT_Face   face    = size->face;
505     T42_Face  t42face = (T42_Face)face;
506     FT_Size   ttsize;
507     FT_Error  error   = T42_Err_Ok;
508
509
510     error = FT_New_Size( t42face->ttf_face, &ttsize );
511     t42size->ttsize = ttsize;
512
513     FT_Activate_Size( ttsize );
514
515     return error;
516   }
517
518
519   FT_LOCAL_DEF( FT_Error )
520   T42_Size_Request( FT_Size          t42size,      /* T42_Size */
521                     FT_Size_Request  req )
522   {
523     T42_Size  size = (T42_Size)t42size;
524     T42_Face  face = (T42_Face)t42size->face;
525     FT_Error  error;
526
527
528     FT_Activate_Size( size->ttsize );
529
530     error = FT_Request_Size( face->ttf_face, req );
531     if ( !error )
532       t42size->metrics = face->ttf_face->size->metrics;
533
534     return error;
535   }
536
537
538   FT_LOCAL_DEF( FT_Error )
539   T42_Size_Select( FT_Size   t42size,         /* T42_Size */
540                    FT_ULong  strike_index )
541   {
542     T42_Size  size = (T42_Size)t42size;
543     T42_Face  face = (T42_Face)t42size->face;
544     FT_Error  error;
545
546
547     FT_Activate_Size( size->ttsize );
548
549     error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
550     if ( !error )
551       t42size->metrics = face->ttf_face->size->metrics;
552
553     return error;
554
555   }
556
557
558   FT_LOCAL_DEF( void )
559   T42_Size_Done( FT_Size  t42size )             /* T42_Size */
560   {
561     T42_Size     size    = (T42_Size)t42size;
562     FT_Face      face    = t42size->face;
563     T42_Face     t42face = (T42_Face)face;
564     FT_ListNode  node;
565
566
567     node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
568     if ( node )
569     {
570       FT_Done_Size( size->ttsize );
571       size->ttsize = NULL;
572     }
573   }
574
575
576   FT_LOCAL_DEF( FT_Error )
577   T42_GlyphSlot_Init( FT_GlyphSlot  t42slot )        /* T42_GlyphSlot */
578   {
579     T42_GlyphSlot  slot    = (T42_GlyphSlot)t42slot;
580     FT_Face        face    = t42slot->face;
581     T42_Face       t42face = (T42_Face)face;
582     FT_GlyphSlot   ttslot;
583     FT_Error       error   = T42_Err_Ok;
584
585
586     if ( face->glyph == NULL )
587     {
588       /* First glyph slot for this face */
589       slot->ttslot = t42face->ttf_face->glyph;
590     }
591     else
592     {
593       error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );
594       slot->ttslot = ttslot;
595     }
596
597     return error;
598   }
599
600
601   FT_LOCAL_DEF( void )
602   T42_GlyphSlot_Done( FT_GlyphSlot  t42slot )       /* T42_GlyphSlot */
603   {
604     T42_GlyphSlot  slot = (T42_GlyphSlot)t42slot;
605
606
607     FT_Done_GlyphSlot( slot->ttslot );
608   }
609
610
611   static void
612   t42_glyphslot_clear( FT_GlyphSlot  slot )
613   {
614     /* free bitmap if needed */
615     ft_glyphslot_free_bitmap( slot );
616
617     /* clear all public fields in the glyph slot */
618     FT_ZERO( &slot->metrics );
619     FT_ZERO( &slot->outline );
620     FT_ZERO( &slot->bitmap );
621
622     slot->bitmap_left   = 0;
623     slot->bitmap_top    = 0;
624     slot->num_subglyphs = 0;
625     slot->subglyphs     = 0;
626     slot->control_data  = 0;
627     slot->control_len   = 0;
628     slot->other         = 0;
629     slot->format        = FT_GLYPH_FORMAT_NONE;
630
631     slot->linearHoriAdvance = 0;
632     slot->linearVertAdvance = 0;
633   }
634
635
636   FT_LOCAL_DEF( FT_Error )
637   T42_GlyphSlot_Load( FT_GlyphSlot  glyph,
638                       FT_Size       size,
639                       FT_UInt       glyph_index,
640                       FT_Int32      load_flags )
641   {
642     FT_Error         error;
643     T42_GlyphSlot    t42slot = (T42_GlyphSlot)glyph;
644     T42_Size         t42size = (T42_Size)size;
645     FT_Driver_Class  ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;
646
647
648     t42_glyphslot_clear( t42slot->ttslot );
649     error = ttclazz->load_glyph( t42slot->ttslot,
650                                  t42size->ttsize,
651                                  glyph_index,
652                                  load_flags | FT_LOAD_NO_BITMAP );
653
654     if ( !error )
655     {
656       glyph->metrics = t42slot->ttslot->metrics;
657
658       glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;
659       glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;
660
661       glyph->format  = t42slot->ttslot->format;
662       glyph->outline = t42slot->ttslot->outline;
663
664       glyph->bitmap      = t42slot->ttslot->bitmap;
665       glyph->bitmap_left = t42slot->ttslot->bitmap_left;
666       glyph->bitmap_top  = t42slot->ttslot->bitmap_top;
667
668       glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;
669       glyph->subglyphs     = t42slot->ttslot->subglyphs;
670
671       glyph->control_data  = t42slot->ttslot->control_data;
672       glyph->control_len   = t42slot->ttslot->control_len;
673     }
674
675     return error;
676   }
677
678
679 /* END */