source: trunk/poppler/freetype2/src/type42/t42objs.c @ 262

Last change on this file since 262 was 262, checked in by Eugene Romanenko, 12 years ago

PDF plugin: freetype library updated to version 2.3.8

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