t42objs.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  t42objs.c                                                              */
00004 /*                                                                         */
00005 /*    Type 42 objects manager (body).                                      */
00006 /*                                                                         */
00007 /*  Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009               */
00008 /*  by Roberto Alameda.                                                    */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include "t42objs.h"
00020 #include "t42parse.h"
00021 #include "t42error.h"
00022 #include FT_INTERNAL_DEBUG_H
00023 #include FT_LIST_H
00024 
00025 
00026 #undef  FT_COMPONENT
00027 #define FT_COMPONENT  trace_t42
00028 
00029 
00030   static FT_Error
00031   T42_Open_Face( T42_Face  face )
00032   {
00033     T42_LoaderRec  loader;
00034     T42_Parser     parser;
00035     T1_Font        type1 = &face->type1;
00036     FT_Memory      memory = face->root.memory;
00037     FT_Error       error;
00038 
00039     PSAux_Service  psaux  = (PSAux_Service)face->psaux;
00040 
00041 
00042     t42_loader_init( &loader, face );
00043 
00044     parser = &loader.parser;
00045 
00046     if ( FT_ALLOC( face->ttf_data, 12 ) )
00047       goto Exit;
00048 
00049     error = t42_parser_init( parser,
00050                              face->root.stream,
00051                              memory,
00052                              psaux);
00053     if ( error )
00054       goto Exit;
00055 
00056     error = t42_parse_dict( face, &loader,
00057                             parser->base_dict, parser->base_len );
00058     if ( error )
00059       goto Exit;
00060 
00061     if ( type1->font_type != 42 )
00062     {
00063       error = T42_Err_Unknown_File_Format;
00064       goto Exit;
00065     }
00066 
00067     /* now, propagate the charstrings and glyphnames tables */
00068     /* to the Type1 data                                    */
00069     type1->num_glyphs = loader.num_glyphs;
00070 
00071     if ( !loader.charstrings.init )
00072     {
00073       FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" ));
00074       error = T42_Err_Invalid_File_Format;
00075     }
00076 
00077     loader.charstrings.init  = 0;
00078     type1->charstrings_block = loader.charstrings.block;
00079     type1->charstrings       = loader.charstrings.elements;
00080     type1->charstrings_len   = loader.charstrings.lengths;
00081 
00082     /* we copy the glyph names `block' and `elements' fields; */
00083     /* the `lengths' field must be released later             */
00084     type1->glyph_names_block    = loader.glyph_names.block;
00085     type1->glyph_names          = (FT_String**)loader.glyph_names.elements;
00086     loader.glyph_names.block    = 0;
00087     loader.glyph_names.elements = 0;
00088 
00089     /* we must now build type1.encoding when we have a custom array */
00090     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
00091     {
00092       FT_Int    charcode, idx, min_char, max_char;
00093       FT_Byte*  char_name;
00094       FT_Byte*  glyph_name;
00095 
00096 
00097       /* OK, we do the following: for each element in the encoding   */
00098       /* table, look up the index of the glyph having the same name  */
00099       /* as defined in the CharStrings array.                        */
00100       /* The index is then stored in type1.encoding.char_index, and  */
00101       /* the name in type1.encoding.char_name                        */
00102 
00103       min_char = 0;
00104       max_char = 0;
00105 
00106       charcode = 0;
00107       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
00108       {
00109         type1->encoding.char_index[charcode] = 0;
00110         type1->encoding.char_name [charcode] = (char *)".notdef";
00111 
00112         char_name = loader.encoding_table.elements[charcode];
00113         if ( char_name )
00114           for ( idx = 0; idx < type1->num_glyphs; idx++ )
00115           {
00116             glyph_name = (FT_Byte*)type1->glyph_names[idx];
00117             if ( ft_strcmp( (const char*)char_name,
00118                             (const char*)glyph_name ) == 0 )
00119             {
00120               type1->encoding.char_index[charcode] = (FT_UShort)idx;
00121               type1->encoding.char_name [charcode] = (char*)glyph_name;
00122 
00123               /* Change min/max encoded char only if glyph name is */
00124               /* not /.notdef                                      */
00125               if ( ft_strcmp( (const char*)".notdef",
00126                               (const char*)glyph_name ) != 0 )
00127               {
00128                 if ( charcode < min_char )
00129                   min_char = charcode;
00130                 if ( charcode >= max_char )
00131                   max_char = charcode + 1;
00132               }
00133               break;
00134             }
00135           }
00136       }
00137 
00138       type1->encoding.code_first = min_char;
00139       type1->encoding.code_last  = max_char;
00140       type1->encoding.num_chars  = loader.num_chars;
00141     }
00142 
00143   Exit:
00144     t42_loader_done( &loader );
00145     return error;
00146   }
00147 
00148 
00149   /***************** Driver Functions *************/
00150 
00151 
00152   FT_LOCAL_DEF( FT_Error )
00153   T42_Face_Init( FT_Stream      stream,
00154                  T42_Face       face,
00155                  FT_Int         face_index,
00156                  FT_Int         num_params,
00157                  FT_Parameter*  params )
00158   {
00159     FT_Error            error;
00160     FT_Service_PsCMaps  psnames;
00161     PSAux_Service       psaux;
00162     FT_Face             root  = (FT_Face)&face->root;
00163     T1_Font             type1 = &face->type1;
00164     PS_FontInfo         info  = &type1->font_info;
00165 
00166     FT_UNUSED( num_params );
00167     FT_UNUSED( params );
00168     FT_UNUSED( face_index );
00169     FT_UNUSED( stream );
00170 
00171 
00172     face->ttf_face       = NULL;
00173     face->root.num_faces = 1;
00174 
00175     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
00176     face->psnames = psnames;
00177 
00178     face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
00179                                            "psaux" );
00180     psaux = (PSAux_Service)face->psaux;
00181 
00182     /* open the tokenizer, this will also check the font format */
00183     error = T42_Open_Face( face );
00184     if ( error )
00185       goto Exit;
00186 
00187     /* if we just wanted to check the format, leave successfully now */
00188     if ( face_index < 0 )
00189       goto Exit;
00190 
00191     /* check the face index */
00192     if ( face_index > 0 )
00193     {
00194       FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
00195       error = T42_Err_Invalid_Argument;
00196       goto Exit;
00197     }
00198 
00199     /* Now load the font program into the face object */
00200 
00201     /* Init the face object fields */
00202     /* Now set up root face fields */
00203 
00204     root->num_glyphs   = type1->num_glyphs;
00205     root->num_charmaps = 0;
00206     root->face_index   = 0;
00207 
00208     root->face_flags = FT_FACE_FLAG_SCALABLE    |
00209                        FT_FACE_FLAG_HORIZONTAL  |
00210                        FT_FACE_FLAG_GLYPH_NAMES;
00211 
00212     if ( info->is_fixed_pitch )
00213       root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
00214 
00215     /* We only set this flag if we have the patented bytecode interpreter. */
00216     /* There are no known `tricky' Type42 fonts that could be loaded with  */
00217     /* the unpatented interpreter.                                         */
00218 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
00219     root->face_flags |= FT_FACE_FLAG_HINTER;
00220 #endif
00221 
00222     /* XXX: TODO -- add kerning with .afm support */
00223 
00224     /* get style name -- be careful, some broken fonts only */
00225     /* have a `/FontName' dictionary entry!                 */
00226     root->family_name = info->family_name;
00227     /* assume "Regular" style if we don't know better */
00228     root->style_name = (char *)"Regular";
00229     if ( root->family_name )
00230     {
00231       char*  full   = info->full_name;
00232       char*  family = root->family_name;
00233 
00234 
00235       if ( full )
00236       {
00237         while ( *full )
00238         {
00239           if ( *full == *family )
00240           {
00241             family++;
00242             full++;
00243           }
00244           else
00245           {
00246             if ( *full == ' ' || *full == '-' )
00247               full++;
00248             else if ( *family == ' ' || *family == '-' )
00249               family++;
00250             else
00251             {
00252               if ( !*family )
00253                 root->style_name = full;
00254               break;
00255             }
00256           }
00257         }
00258       }
00259     }
00260     else
00261     {
00262       /* do we have a `/FontName'? */
00263       if ( type1->font_name )
00264         root->family_name = type1->font_name;
00265     }
00266 
00267     /* no embedded bitmap support */
00268     root->num_fixed_sizes = 0;
00269     root->available_sizes = 0;
00270 
00271     /* Load the TTF font embedded in the T42 font */
00272     {
00273       FT_Open_Args  args;
00274 
00275 
00276       args.flags       = FT_OPEN_MEMORY;
00277       args.memory_base = face->ttf_data;
00278       args.memory_size = face->ttf_size;
00279 
00280       if ( num_params )
00281       {
00282         args.flags     |= FT_OPEN_PARAMS;
00283         args.num_params = num_params;
00284         args.params     = params;
00285       }
00286 
00287       error = FT_Open_Face( FT_FACE_LIBRARY( face ),
00288                             &args, 0, &face->ttf_face );
00289     }
00290 
00291     if ( error )
00292       goto Exit;
00293 
00294     FT_Done_Size( face->ttf_face->size );
00295 
00296     /* Ignore info in FontInfo dictionary and use the info from the  */
00297     /* loaded TTF font.  The PostScript interpreter also ignores it. */
00298     root->bbox         = face->ttf_face->bbox;
00299     root->units_per_EM = face->ttf_face->units_per_EM;
00300 
00301     root->ascender  = face->ttf_face->ascender;
00302     root->descender = face->ttf_face->descender;
00303     root->height    = face->ttf_face->height;
00304 
00305     root->max_advance_width  = face->ttf_face->max_advance_width;
00306     root->max_advance_height = face->ttf_face->max_advance_height;
00307 
00308     root->underline_position  = (FT_Short)info->underline_position;
00309     root->underline_thickness = (FT_Short)info->underline_thickness;
00310 
00311     /* compute style flags */
00312     root->style_flags = 0;
00313     if ( info->italic_angle )
00314       root->style_flags |= FT_STYLE_FLAG_ITALIC;
00315 
00316     if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
00317       root->style_flags |= FT_STYLE_FLAG_BOLD;
00318 
00319     if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
00320       root->face_flags |= FT_FACE_FLAG_VERTICAL;
00321 
00322     {
00323       if ( psnames && psaux )
00324       {
00325         FT_CharMapRec    charmap;
00326         T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
00327         FT_CMap_Class    clazz;
00328 
00329 
00330         charmap.face = root;
00331 
00332         /* first of all, try to synthesize a Unicode charmap */
00333         charmap.platform_id = 3;
00334         charmap.encoding_id = 1;
00335         charmap.encoding    = FT_ENCODING_UNICODE;
00336 
00337         FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
00338 
00339         /* now, generate an Adobe Standard encoding when appropriate */
00340         charmap.platform_id = 7;
00341         clazz               = NULL;
00342 
00343         switch ( type1->encoding_type )
00344         {
00345         case T1_ENCODING_TYPE_STANDARD:
00346           charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
00347           charmap.encoding_id = 0;
00348           clazz               = cmap_classes->standard;
00349           break;
00350 
00351         case T1_ENCODING_TYPE_EXPERT:
00352           charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
00353           charmap.encoding_id = 1;
00354           clazz               = cmap_classes->expert;
00355           break;
00356 
00357         case T1_ENCODING_TYPE_ARRAY:
00358           charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
00359           charmap.encoding_id = 2;
00360           clazz               = cmap_classes->custom;
00361           break;
00362 
00363         case T1_ENCODING_TYPE_ISOLATIN1:
00364           charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
00365           charmap.encoding_id = 3;
00366           clazz               = cmap_classes->unicode;
00367           break;
00368 
00369         default:
00370           ;
00371         }
00372 
00373         if ( clazz )
00374           FT_CMap_New( clazz, NULL, &charmap, NULL );
00375 
00376 #if 0
00377         /* Select default charmap */
00378         if ( root->num_charmaps )
00379           root->charmap = root->charmaps[0];
00380 #endif
00381       }
00382     }
00383   Exit:
00384     return error;
00385   }
00386 
00387 
00388   FT_LOCAL_DEF( void )
00389   T42_Face_Done( T42_Face  face )
00390   {
00391     T1_Font      type1;
00392     PS_FontInfo  info;
00393     FT_Memory    memory;
00394 
00395 
00396     if ( !face )
00397       return;
00398 
00399     type1  = &face->type1;
00400     info   = &type1->font_info;
00401     memory = face->root.memory;
00402 
00403     /* delete internal ttf face prior to freeing face->ttf_data */
00404     if ( face->ttf_face )
00405       FT_Done_Face( face->ttf_face );
00406 
00407     /* release font info strings */
00408     FT_FREE( info->version );
00409     FT_FREE( info->notice );
00410     FT_FREE( info->full_name );
00411     FT_FREE( info->family_name );
00412     FT_FREE( info->weight );
00413 
00414     /* release top dictionary */
00415     FT_FREE( type1->charstrings_len );
00416     FT_FREE( type1->charstrings );
00417     FT_FREE( type1->glyph_names );
00418 
00419     FT_FREE( type1->charstrings_block );
00420     FT_FREE( type1->glyph_names_block );
00421 
00422     FT_FREE( type1->encoding.char_index );
00423     FT_FREE( type1->encoding.char_name );
00424     FT_FREE( type1->font_name );
00425 
00426     FT_FREE( face->ttf_data );
00427 
00428 #if 0
00429     /* release afm data if present */
00430     if ( face->afm_data )
00431       T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
00432 #endif
00433 
00434     /* release unicode map, if any */
00435     FT_FREE( face->unicode_map.maps );
00436     face->unicode_map.num_maps = 0;
00437 
00438     face->root.family_name = 0;
00439     face->root.style_name  = 0;
00440   }
00441 
00442 
00443   /*************************************************************************/
00444   /*                                                                       */
00445   /* <Function>                                                            */
00446   /*    T42_Driver_Init                                                    */
00447   /*                                                                       */
00448   /* <Description>                                                         */
00449   /*    Initializes a given Type 42 driver object.                         */
00450   /*                                                                       */
00451   /* <Input>                                                               */
00452   /*    driver :: A handle to the target driver object.                    */
00453   /*                                                                       */
00454   /* <Return>                                                              */
00455   /*    FreeType error code.  0 means success.                             */
00456   /*                                                                       */
00457   FT_LOCAL_DEF( FT_Error )
00458   T42_Driver_Init( T42_Driver  driver )
00459   {
00460     FT_Module  ttmodule;
00461 
00462 
00463     ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" );
00464     driver->ttclazz = (FT_Driver_Class)ttmodule->clazz;
00465 
00466     return T42_Err_Ok;
00467   }
00468 
00469 
00470   FT_LOCAL_DEF( void )
00471   T42_Driver_Done( T42_Driver  driver )
00472   {
00473     FT_UNUSED( driver );
00474   }
00475 
00476 
00477   FT_LOCAL_DEF( FT_Error )
00478   T42_Size_Init( T42_Size  size )
00479   {
00480     FT_Face   face = size->root.face;
00481     T42_Face  t42face = (T42_Face)face;
00482     FT_Size   ttsize;
00483     FT_Error  error   = T42_Err_Ok;
00484 
00485 
00486     error = FT_New_Size( t42face->ttf_face, &ttsize );
00487     size->ttsize = ttsize;
00488 
00489     FT_Activate_Size( ttsize );
00490 
00491     return error;
00492   }
00493 
00494 
00495   FT_LOCAL_DEF( FT_Error )
00496   T42_Size_Request( T42_Size         size,
00497                     FT_Size_Request  req )
00498   {
00499     T42_Face  face = (T42_Face)size->root.face;
00500     FT_Error  error;
00501 
00502 
00503     FT_Activate_Size( size->ttsize );
00504 
00505     error = FT_Request_Size( face->ttf_face, req );
00506     if ( !error )
00507       ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;
00508 
00509     return error;
00510   }
00511 
00512 
00513   FT_LOCAL_DEF( FT_Error )
00514   T42_Size_Select( T42_Size  size,
00515                    FT_ULong  strike_index )
00516   {
00517     T42_Face  face = (T42_Face)size->root.face;
00518     FT_Error  error;
00519 
00520 
00521     FT_Activate_Size( size->ttsize );
00522 
00523     error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
00524     if ( !error )
00525       ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;
00526 
00527     return error;
00528 
00529   }
00530 
00531 
00532   FT_LOCAL_DEF( void )
00533   T42_Size_Done( T42_Size  size )
00534   {
00535     FT_Face      face    = size->root.face;
00536     T42_Face     t42face = (T42_Face)face;
00537     FT_ListNode  node;
00538 
00539 
00540     node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
00541     if ( node )
00542     {
00543       FT_Done_Size( size->ttsize );
00544       size->ttsize = NULL;
00545     }
00546   }
00547 
00548 
00549   FT_LOCAL_DEF( FT_Error )
00550   T42_GlyphSlot_Init( T42_GlyphSlot  slot )
00551   {
00552     FT_Face       face    = slot->root.face;
00553     T42_Face      t42face = (T42_Face)face;
00554     FT_GlyphSlot  ttslot;
00555     FT_Error      error   = T42_Err_Ok;
00556 
00557 
00558     if ( face->glyph == NULL )
00559     {
00560       /* First glyph slot for this face */
00561       slot->ttslot = t42face->ttf_face->glyph;
00562     }
00563     else
00564     {
00565       error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );
00566       slot->ttslot = ttslot;
00567     }
00568 
00569     return error;
00570   }
00571 
00572 
00573   FT_LOCAL_DEF( void )
00574   T42_GlyphSlot_Done( T42_GlyphSlot slot )
00575   {
00576     FT_Done_GlyphSlot( slot->ttslot );
00577   }
00578 
00579 
00580   static void
00581   t42_glyphslot_clear( FT_GlyphSlot  slot )
00582   {
00583     /* free bitmap if needed */
00584     ft_glyphslot_free_bitmap( slot );
00585 
00586     /* clear all public fields in the glyph slot */
00587     FT_ZERO( &slot->metrics );
00588     FT_ZERO( &slot->outline );
00589     FT_ZERO( &slot->bitmap );
00590 
00591     slot->bitmap_left   = 0;
00592     slot->bitmap_top    = 0;
00593     slot->num_subglyphs = 0;
00594     slot->subglyphs     = 0;
00595     slot->control_data  = 0;
00596     slot->control_len   = 0;
00597     slot->other         = 0;
00598     slot->format        = FT_GLYPH_FORMAT_NONE;
00599 
00600     slot->linearHoriAdvance = 0;
00601     slot->linearVertAdvance = 0;
00602   }
00603 
00604 
00605   FT_LOCAL_DEF( FT_Error )
00606   T42_GlyphSlot_Load( FT_GlyphSlot  glyph,
00607                       FT_Size       size,
00608                       FT_UInt       glyph_index,
00609                       FT_Int32      load_flags )
00610   {
00611     FT_Error         error;
00612     T42_GlyphSlot    t42slot = (T42_GlyphSlot)glyph;
00613     T42_Size         t42size = (T42_Size)size;
00614     FT_Driver_Class  ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;
00615 
00616 
00617     t42_glyphslot_clear( t42slot->ttslot );
00618     error = ttclazz->load_glyph( t42slot->ttslot,
00619                                  t42size->ttsize,
00620                                  glyph_index,
00621                                  load_flags | FT_LOAD_NO_BITMAP );
00622 
00623     if ( !error )
00624     {
00625       glyph->metrics = t42slot->ttslot->metrics;
00626 
00627       glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;
00628       glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;
00629 
00630       glyph->format  = t42slot->ttslot->format;
00631       glyph->outline = t42slot->ttslot->outline;
00632 
00633       glyph->bitmap      = t42slot->ttslot->bitmap;
00634       glyph->bitmap_left = t42slot->ttslot->bitmap_left;
00635       glyph->bitmap_top  = t42slot->ttslot->bitmap_top;
00636 
00637       glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;
00638       glyph->subglyphs     = t42slot->ttslot->subglyphs;
00639 
00640       glyph->control_data  = t42slot->ttslot->control_data;
00641       glyph->control_len   = t42slot->ttslot->control_len;
00642     }
00643 
00644     return error;
00645   }
00646 
00647 
00648 /* END */

Generated on Tue Jul 5 14:13:54 2011 for ROOT_528-00b_version by  doxygen 1.5.1