t1objs.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  t1objs.c                                                               */
00004 /*                                                                         */
00005 /*    Type 1 objects manager (body).                                       */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
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 <ft2build.h>
00020 #include FT_INTERNAL_CALC_H
00021 #include FT_INTERNAL_DEBUG_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_TRUETYPE_IDS_H
00024 
00025 #include "t1gload.h"
00026 #include "t1load.h"
00027 
00028 #include "t1errors.h"
00029 
00030 #ifndef T1_CONFIG_OPTION_NO_AFM
00031 #include "t1afm.h"
00032 #endif
00033 
00034 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00035 #include FT_INTERNAL_POSTSCRIPT_AUX_H
00036 
00037 
00038   /*************************************************************************/
00039   /*                                                                       */
00040   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00041   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00042   /* messages during execution.                                            */
00043   /*                                                                       */
00044 #undef  FT_COMPONENT
00045 #define FT_COMPONENT  trace_t1objs
00046 
00047 
00048   /*************************************************************************/
00049   /*                                                                       */
00050   /*                            SIZE FUNCTIONS                             */
00051   /*                                                                       */
00052   /*  note that we store the global hints in the size's "internal" root    */
00053   /*  field                                                                */
00054   /*                                                                       */
00055   /*************************************************************************/
00056 
00057 
00058   static PSH_Globals_Funcs
00059   T1_Size_Get_Globals_Funcs( T1_Size  size )
00060   {
00061     T1_Face           face     = (T1_Face)size->root.face;
00062     PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;
00063     FT_Module         module;
00064 
00065 
00066     module = FT_Get_Module( size->root.face->driver->root.library,
00067                             "pshinter" );
00068     return ( module && pshinter && pshinter->get_globals_funcs )
00069            ? pshinter->get_globals_funcs( module )
00070            : 0 ;
00071   }
00072 
00073 
00074   FT_LOCAL_DEF( void )
00075   T1_Size_Done( T1_Size  size )
00076   {
00077     if ( size->root.internal )
00078     {
00079       PSH_Globals_Funcs  funcs;
00080 
00081 
00082       funcs = T1_Size_Get_Globals_Funcs( size );
00083       if ( funcs )
00084         funcs->destroy( (PSH_Globals)size->root.internal );
00085 
00086       size->root.internal = 0;
00087     }
00088   }
00089 
00090 
00091   FT_LOCAL_DEF( FT_Error )
00092   T1_Size_Init( T1_Size  size )
00093   {
00094     FT_Error           error = T1_Err_Ok;
00095     PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
00096 
00097 
00098     if ( funcs )
00099     {
00100       PSH_Globals  globals;
00101       T1_Face      face = (T1_Face)size->root.face;
00102 
00103 
00104       error = funcs->create( size->root.face->memory,
00105                              &face->type1.private_dict, &globals );
00106       if ( !error )
00107         size->root.internal = (FT_Size_Internal)(void*)globals;
00108     }
00109 
00110     return error;
00111   }
00112 
00113 
00114   FT_LOCAL_DEF( FT_Error )
00115   T1_Size_Request( T1_Size          size,
00116                    FT_Size_Request  req )
00117   {
00118     PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
00119 
00120 
00121     FT_Request_Metrics( size->root.face, req );
00122 
00123     if ( funcs )
00124       funcs->set_scale( (PSH_Globals)size->root.internal,
00125                         size->root.metrics.x_scale,
00126                         size->root.metrics.y_scale,
00127                         0, 0 );
00128 
00129     return T1_Err_Ok;
00130   }
00131 
00132 
00133   /*************************************************************************/
00134   /*                                                                       */
00135   /*                            SLOT  FUNCTIONS                            */
00136   /*                                                                       */
00137   /*************************************************************************/
00138 
00139   FT_LOCAL_DEF( void )
00140   T1_GlyphSlot_Done( T1_GlyphSlot  slot )
00141   {
00142     slot->root.internal->glyph_hints = 0;
00143   }
00144 
00145 
00146   FT_LOCAL_DEF( FT_Error )
00147   T1_GlyphSlot_Init( T1_GlyphSlot  slot )
00148   {
00149     T1_Face           face;
00150     PSHinter_Service  pshinter;
00151 
00152 
00153     face     = (T1_Face)slot->root.face;
00154     pshinter = (PSHinter_Service)face->pshinter;
00155 
00156     if ( pshinter )
00157     {
00158       FT_Module  module;
00159 
00160 
00161       module = FT_Get_Module( slot->root.face->driver->root.library, "pshinter" );
00162       if (module)
00163       {
00164         T1_Hints_Funcs  funcs;
00165 
00166         funcs = pshinter->get_t1_funcs( module );
00167         slot->root.internal->glyph_hints = (void*)funcs;
00168       }
00169     }
00170     return 0;
00171   }
00172 
00173 
00174   /*************************************************************************/
00175   /*                                                                       */
00176   /*                            FACE  FUNCTIONS                            */
00177   /*                                                                       */
00178   /*************************************************************************/
00179 
00180 
00181   /*************************************************************************/
00182   /*                                                                       */
00183   /* <Function>                                                            */
00184   /*    T1_Face_Done                                                       */
00185   /*                                                                       */
00186   /* <Description>                                                         */
00187   /*    The face object destructor.                                        */
00188   /*                                                                       */
00189   /* <Input>                                                               */
00190   /*    face :: A typeless pointer to the face object to destroy.          */
00191   /*                                                                       */
00192   FT_LOCAL_DEF( void )
00193   T1_Face_Done( T1_Face  face )
00194   {
00195     FT_Memory  memory;
00196     T1_Font    type1;
00197 
00198 
00199     if ( !face )
00200       return;
00201 
00202     memory = face->root.memory;
00203     type1  = &face->type1;
00204 
00205 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
00206     /* release multiple masters information */
00207     FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
00208 
00209     if ( face->buildchar )
00210     {
00211       FT_FREE( face->buildchar );
00212 
00213       face->buildchar     = NULL;
00214       face->len_buildchar = 0;
00215     }
00216 
00217     T1_Done_Blend( face );
00218     face->blend = 0;
00219 #endif
00220 
00221     /* release font info strings */
00222     {
00223       PS_FontInfo  info = &type1->font_info;
00224 
00225 
00226       FT_FREE( info->version );
00227       FT_FREE( info->notice );
00228       FT_FREE( info->full_name );
00229       FT_FREE( info->family_name );
00230       FT_FREE( info->weight );
00231     }
00232 
00233     /* release top dictionary */
00234     FT_FREE( type1->charstrings_len );
00235     FT_FREE( type1->charstrings );
00236     FT_FREE( type1->glyph_names );
00237 
00238     FT_FREE( type1->subrs );
00239     FT_FREE( type1->subrs_len );
00240 
00241     FT_FREE( type1->subrs_block );
00242     FT_FREE( type1->charstrings_block );
00243     FT_FREE( type1->glyph_names_block );
00244 
00245     FT_FREE( type1->encoding.char_index );
00246     FT_FREE( type1->encoding.char_name );
00247     FT_FREE( type1->font_name );
00248 
00249 #ifndef T1_CONFIG_OPTION_NO_AFM
00250     /* release afm data if present */
00251     if ( face->afm_data )
00252       T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );
00253 #endif
00254 
00255     /* release unicode map, if any */
00256 #if 0
00257     FT_FREE( face->unicode_map_rec.maps );
00258     face->unicode_map_rec.num_maps = 0;
00259     face->unicode_map              = NULL;
00260 #endif
00261 
00262     face->root.family_name = NULL;
00263     face->root.style_name  = NULL;
00264   }
00265 
00266 
00267   /*************************************************************************/
00268   /*                                                                       */
00269   /* <Function>                                                            */
00270   /*    T1_Face_Init                                                       */
00271   /*                                                                       */
00272   /* <Description>                                                         */
00273   /*    The face object constructor.                                       */
00274   /*                                                                       */
00275   /* <Input>                                                               */
00276   /*    stream     ::  input stream where to load font data.               */
00277   /*                                                                       */
00278   /*    face_index :: The index of the font face in the resource.          */
00279   /*                                                                       */
00280   /*    num_params :: Number of additional generic parameters.  Ignored.   */
00281   /*                                                                       */
00282   /*    params     :: Additional generic parameters.  Ignored.             */
00283   /*                                                                       */
00284   /* <InOut>                                                               */
00285   /*    face       :: The face record to build.                            */
00286   /*                                                                       */
00287   /* <Return>                                                              */
00288   /*    FreeType error code.  0 means success.                             */
00289   /*                                                                       */
00290   FT_LOCAL_DEF( FT_Error )
00291   T1_Face_Init( FT_Stream      stream,
00292                 T1_Face        face,
00293                 FT_Int         face_index,
00294                 FT_Int         num_params,
00295                 FT_Parameter*  params )
00296   {
00297     FT_Error            error;
00298     FT_Service_PsCMaps  psnames;
00299     PSAux_Service       psaux;
00300     T1_Font             type1 = &face->type1;
00301     PS_FontInfo         info = &type1->font_info;
00302 
00303     FT_UNUSED( num_params );
00304     FT_UNUSED( params );
00305     FT_UNUSED( stream );
00306 
00307 
00308     face->root.num_faces = 1;
00309 
00310     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
00311     face->psnames = psnames;
00312 
00313     face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
00314                                            "psaux" );
00315     psaux = (PSAux_Service)face->psaux;
00316 
00317     face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
00318                                               "pshinter" );
00319 
00320     /* open the tokenizer; this will also check the font format */
00321     error = T1_Open_Face( face );
00322     if ( error )
00323       goto Exit;
00324 
00325     /* if we just wanted to check the format, leave successfully now */
00326     if ( face_index < 0 )
00327       goto Exit;
00328 
00329     /* check the face index */
00330     if ( face_index > 0 )
00331     {
00332       FT_ERROR(( "T1_Face_Init: invalid face index\n" ));
00333       error = T1_Err_Invalid_Argument;
00334       goto Exit;
00335     }
00336 
00337     /* now load the font program into the face object */
00338 
00339     /* initialize the face object fields */
00340 
00341     /* set up root face fields */
00342     {
00343       FT_Face  root = (FT_Face)&face->root;
00344 
00345 
00346       root->num_glyphs = type1->num_glyphs;
00347       root->face_index = 0;
00348 
00349       root->face_flags = FT_FACE_FLAG_SCALABLE    |
00350                          FT_FACE_FLAG_HORIZONTAL  |
00351                          FT_FACE_FLAG_GLYPH_NAMES |
00352                          FT_FACE_FLAG_HINTER;
00353 
00354       if ( info->is_fixed_pitch )
00355         root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
00356 
00357       if ( face->blend )
00358         root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
00359 
00360       /* XXX: TODO -- add kerning with .afm support */
00361 
00362 
00363       /* The following code to extract the family and the style is very   */
00364       /* simplistic and might get some things wrong.  For a full-featured */
00365       /* algorithm you might have a look at the whitepaper given at       */
00366       /*                                                                  */
00367       /*   http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */
00368 
00369       /* get style name -- be careful, some broken fonts only */
00370       /* have a `/FontName' dictionary entry!                 */
00371       root->family_name = info->family_name;
00372       root->style_name  = NULL;
00373 
00374       if ( root->family_name )
00375       {
00376         char*  full   = info->full_name;
00377         char*  family = root->family_name;
00378 
00379 
00380         if ( full )
00381         {
00382           FT_Bool  the_same = TRUE;
00383 
00384 
00385           while ( *full )
00386           {
00387             if ( *full == *family )
00388             {
00389               family++;
00390               full++;
00391             }
00392             else
00393             {
00394               if ( *full == ' ' || *full == '-' )
00395                 full++;
00396               else if ( *family == ' ' || *family == '-' )
00397                 family++;
00398               else
00399               {
00400                 the_same = FALSE;
00401 
00402                 if ( !*family )
00403                   root->style_name = full;
00404                 break;
00405               }
00406             }
00407           }
00408 
00409           if ( the_same )
00410             root->style_name = (char *)"Regular";
00411         }
00412       }
00413       else
00414       {
00415         /* do we have a `/FontName'? */
00416         if ( type1->font_name )
00417           root->family_name = type1->font_name;
00418       }
00419 
00420       if ( !root->style_name )
00421       {
00422         if ( info->weight )
00423           root->style_name = info->weight;
00424         else
00425           /* assume `Regular' style because we don't know better */
00426           root->style_name = (char *)"Regular";
00427       }
00428 
00429       /* compute style flags */
00430       root->style_flags = 0;
00431       if ( info->italic_angle )
00432         root->style_flags |= FT_STYLE_FLAG_ITALIC;
00433       if ( info->weight )
00434       {
00435         if ( !ft_strcmp( info->weight, "Bold"  ) ||
00436              !ft_strcmp( info->weight, "Black" ) )
00437           root->style_flags |= FT_STYLE_FLAG_BOLD;
00438       }
00439 
00440       /* no embedded bitmap support */
00441       root->num_fixed_sizes = 0;
00442       root->available_sizes = 0;
00443 
00444       root->bbox.xMin =   type1->font_bbox.xMin            >> 16;
00445       root->bbox.yMin =   type1->font_bbox.yMin            >> 16;
00446       /* no `U' suffix here to 0xFFFF! */
00447       root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16;
00448       root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16;
00449 
00450       /* Set units_per_EM if we didn't set it in parse_font_matrix. */
00451       if ( !root->units_per_EM )
00452         root->units_per_EM = 1000;
00453 
00454       root->ascender  = (FT_Short)( root->bbox.yMax );
00455       root->descender = (FT_Short)( root->bbox.yMin );
00456 
00457       root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 );
00458       if ( root->height < root->ascender - root->descender )
00459         root->height = (FT_Short)( root->ascender - root->descender );
00460 
00461       /* now compute the maximum advance width */
00462       root->max_advance_width =
00463         (FT_Short)( root->bbox.xMax );
00464       {
00465         FT_Pos  max_advance;
00466 
00467 
00468         error = T1_Compute_Max_Advance( face, &max_advance );
00469 
00470         /* in case of error, keep the standard width */
00471         if ( !error )
00472           root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance );
00473         else
00474           error = T1_Err_Ok;   /* clear error */
00475       }
00476 
00477       root->max_advance_height = root->height;
00478 
00479       root->underline_position  = (FT_Short)info->underline_position;
00480       root->underline_thickness = (FT_Short)info->underline_thickness;
00481     }
00482 
00483     {
00484       FT_Face  root = &face->root;
00485 
00486 
00487       if ( psnames && psaux )
00488       {
00489         FT_CharMapRec    charmap;
00490         T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
00491         FT_CMap_Class    clazz;
00492 
00493 
00494         charmap.face = root;
00495 
00496         /* first of all, try to synthesize a Unicode charmap */
00497         charmap.platform_id = 3;
00498         charmap.encoding_id = 1;
00499         charmap.encoding    = FT_ENCODING_UNICODE;
00500 
00501         FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
00502 
00503         /* now, generate an Adobe Standard encoding when appropriate */
00504         charmap.platform_id = 7;
00505         clazz               = NULL;
00506 
00507         switch ( type1->encoding_type )
00508         {
00509         case T1_ENCODING_TYPE_STANDARD:
00510           charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
00511           charmap.encoding_id = TT_ADOBE_ID_STANDARD;
00512           clazz               = cmap_classes->standard;
00513           break;
00514 
00515         case T1_ENCODING_TYPE_EXPERT:
00516           charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
00517           charmap.encoding_id = TT_ADOBE_ID_EXPERT;
00518           clazz               = cmap_classes->expert;
00519           break;
00520 
00521         case T1_ENCODING_TYPE_ARRAY:
00522           charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
00523           charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
00524           clazz               = cmap_classes->custom;
00525           break;
00526 
00527         case T1_ENCODING_TYPE_ISOLATIN1:
00528           charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
00529           charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
00530           clazz               = cmap_classes->unicode;
00531           break;
00532 
00533         default:
00534           ;
00535         }
00536 
00537         if ( clazz )
00538           FT_CMap_New( clazz, NULL, &charmap, NULL );
00539 
00540 #if 0
00541         /* Select default charmap */
00542         if (root->num_charmaps)
00543           root->charmap = root->charmaps[0];
00544 #endif
00545       }
00546     }
00547 
00548   Exit:
00549     return error;
00550   }
00551 
00552 
00553   /*************************************************************************/
00554   /*                                                                       */
00555   /* <Function>                                                            */
00556   /*    T1_Driver_Init                                                     */
00557   /*                                                                       */
00558   /* <Description>                                                         */
00559   /*    Initializes a given Type 1 driver object.                          */
00560   /*                                                                       */
00561   /* <Input>                                                               */
00562   /*    driver :: A handle to the target driver object.                    */
00563   /*                                                                       */
00564   /* <Return>                                                              */
00565   /*    FreeType error code.  0 means success.                             */
00566   /*                                                                       */
00567   FT_LOCAL_DEF( FT_Error )
00568   T1_Driver_Init( T1_Driver  driver )
00569   {
00570     FT_UNUSED( driver );
00571 
00572     return T1_Err_Ok;
00573   }
00574 
00575 
00576   /*************************************************************************/
00577   /*                                                                       */
00578   /* <Function>                                                            */
00579   /*    T1_Driver_Done                                                     */
00580   /*                                                                       */
00581   /* <Description>                                                         */
00582   /*    Finalizes a given Type 1 driver.                                   */
00583   /*                                                                       */
00584   /* <Input>                                                               */
00585   /*    driver :: A handle to the target Type 1 driver.                    */
00586   /*                                                                       */
00587   FT_LOCAL_DEF( void )
00588   T1_Driver_Done( T1_Driver  driver )
00589   {
00590     FT_UNUSED( driver );
00591   }
00592 
00593 
00594 /* END */

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