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