source: trunk/poppler/freetype-2.1.10/src/type42/t42objs.c @ 2

Last change on this file since 2 was 2, checked in by Eugene Romanenko, 15 years ago

First import

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