Home | History | Annotate | Download | only in cid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  cidobjs.c                                                              */
      4 /*                                                                         */
      5 /*    CID objects manager (body).                                          */
      6 /*                                                                         */
      7 /*  Copyright 1996-2015 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      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 <ft2build.h>
     20 #include FT_INTERNAL_DEBUG_H
     21 #include FT_INTERNAL_STREAM_H
     22 
     23 #include "cidgload.h"
     24 #include "cidload.h"
     25 
     26 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
     27 #include FT_INTERNAL_POSTSCRIPT_AUX_H
     28 #include FT_INTERNAL_POSTSCRIPT_HINTS_H
     29 
     30 #include "ciderrs.h"
     31 
     32 
     33   /*************************************************************************/
     34   /*                                                                       */
     35   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     36   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     37   /* messages during execution.                                            */
     38   /*                                                                       */
     39 #undef  FT_COMPONENT
     40 #define FT_COMPONENT  trace_cidobjs
     41 
     42 
     43   /*************************************************************************/
     44   /*                                                                       */
     45   /*                            SLOT  FUNCTIONS                            */
     46   /*                                                                       */
     47   /*************************************************************************/
     48 
     49   FT_LOCAL_DEF( void )
     50   cid_slot_done( FT_GlyphSlot  slot )
     51   {
     52     slot->internal->glyph_hints = NULL;
     53   }
     54 
     55 
     56   FT_LOCAL_DEF( FT_Error )
     57   cid_slot_init( FT_GlyphSlot  slot )
     58   {
     59     CID_Face          face;
     60     PSHinter_Service  pshinter;
     61 
     62 
     63     face     = (CID_Face)slot->face;
     64     pshinter = (PSHinter_Service)face->pshinter;
     65 
     66     if ( pshinter )
     67     {
     68       FT_Module  module;
     69 
     70 
     71       module = FT_Get_Module( slot->face->driver->root.library,
     72                               "pshinter" );
     73       if ( module )
     74       {
     75         T1_Hints_Funcs  funcs;
     76 
     77 
     78         funcs = pshinter->get_t1_funcs( module );
     79         slot->internal->glyph_hints = (void*)funcs;
     80       }
     81     }
     82 
     83     return 0;
     84   }
     85 
     86 
     87   /*************************************************************************/
     88   /*                                                                       */
     89   /*                           SIZE  FUNCTIONS                             */
     90   /*                                                                       */
     91   /*************************************************************************/
     92 
     93 
     94   static PSH_Globals_Funcs
     95   cid_size_get_globals_funcs( CID_Size  size )
     96   {
     97     CID_Face          face     = (CID_Face)size->root.face;
     98     PSHinter_Service  pshinter = (PSHinter_Service)face->pshinter;
     99     FT_Module         module;
    100 
    101 
    102     module = FT_Get_Module( size->root.face->driver->root.library,
    103                             "pshinter" );
    104     return ( module && pshinter && pshinter->get_globals_funcs )
    105            ? pshinter->get_globals_funcs( module )
    106            : 0;
    107   }
    108 
    109 
    110   FT_LOCAL_DEF( void )
    111   cid_size_done( FT_Size  cidsize )         /* CID_Size */
    112   {
    113     CID_Size  size = (CID_Size)cidsize;
    114 
    115 
    116     if ( cidsize->internal )
    117     {
    118       PSH_Globals_Funcs  funcs;
    119 
    120 
    121       funcs = cid_size_get_globals_funcs( size );
    122       if ( funcs )
    123         funcs->destroy( (PSH_Globals)cidsize->internal );
    124 
    125       cidsize->internal = NULL;
    126     }
    127   }
    128 
    129 
    130   FT_LOCAL_DEF( FT_Error )
    131   cid_size_init( FT_Size  cidsize )     /* CID_Size */
    132   {
    133     CID_Size           size  = (CID_Size)cidsize;
    134     FT_Error           error = FT_Err_Ok;
    135     PSH_Globals_Funcs  funcs = cid_size_get_globals_funcs( size );
    136 
    137 
    138     if ( funcs )
    139     {
    140       PSH_Globals   globals;
    141       CID_Face      face = (CID_Face)cidsize->face;
    142       CID_FaceDict  dict = face->cid.font_dicts + face->root.face_index;
    143       PS_Private    priv = &dict->private_dict;
    144 
    145 
    146       error = funcs->create( cidsize->face->memory, priv, &globals );
    147       if ( !error )
    148         cidsize->internal = (FT_Size_Internal)(void*)globals;
    149     }
    150 
    151     return error;
    152   }
    153 
    154 
    155   FT_LOCAL( FT_Error )
    156   cid_size_request( FT_Size          size,
    157                     FT_Size_Request  req )
    158   {
    159     PSH_Globals_Funcs  funcs;
    160 
    161 
    162     FT_Request_Metrics( size->face, req );
    163 
    164     funcs = cid_size_get_globals_funcs( (CID_Size)size );
    165 
    166     if ( funcs )
    167       funcs->set_scale( (PSH_Globals)size->internal,
    168                         size->metrics.x_scale,
    169                         size->metrics.y_scale,
    170                         0, 0 );
    171 
    172     return FT_Err_Ok;
    173   }
    174 
    175 
    176   /*************************************************************************/
    177   /*                                                                       */
    178   /*                           FACE  FUNCTIONS                             */
    179   /*                                                                       */
    180   /*************************************************************************/
    181 
    182   /*************************************************************************/
    183   /*                                                                       */
    184   /* <Function>                                                            */
    185   /*    cid_face_done                                                      */
    186   /*                                                                       */
    187   /* <Description>                                                         */
    188   /*    Finalizes a given face object.                                     */
    189   /*                                                                       */
    190   /* <Input>                                                               */
    191   /*    face :: A pointer to the face object to destroy.                   */
    192   /*                                                                       */
    193   FT_LOCAL_DEF( void )
    194   cid_face_done( FT_Face  cidface )         /* CID_Face */
    195   {
    196     CID_Face      face = (CID_Face)cidface;
    197     FT_Memory     memory;
    198     CID_FaceInfo  cid;
    199     PS_FontInfo   info;
    200 
    201 
    202     if ( !face )
    203       return;
    204 
    205     cid    = &face->cid;
    206     info   = &cid->font_info;
    207     memory = cidface->memory;
    208 
    209     /* release subrs */
    210     if ( face->subrs )
    211     {
    212       FT_Int  n;
    213 
    214 
    215       for ( n = 0; n < cid->num_dicts; n++ )
    216       {
    217         CID_Subrs  subr = face->subrs + n;
    218 
    219 
    220         if ( subr->code )
    221         {
    222           FT_FREE( subr->code[0] );
    223           FT_FREE( subr->code );
    224         }
    225       }
    226 
    227       FT_FREE( face->subrs );
    228     }
    229 
    230     /* release FontInfo strings */
    231     FT_FREE( info->version );
    232     FT_FREE( info->notice );
    233     FT_FREE( info->full_name );
    234     FT_FREE( info->family_name );
    235     FT_FREE( info->weight );
    236 
    237     /* release font dictionaries */
    238     FT_FREE( cid->font_dicts );
    239     cid->num_dicts = 0;
    240 
    241     /* release other strings */
    242     FT_FREE( cid->cid_font_name );
    243     FT_FREE( cid->registry );
    244     FT_FREE( cid->ordering );
    245 
    246     cidface->family_name = NULL;
    247     cidface->style_name  = NULL;
    248 
    249     FT_FREE( face->binary_data );
    250     FT_FREE( face->cid_stream );
    251   }
    252 
    253 
    254   /*************************************************************************/
    255   /*                                                                       */
    256   /* <Function>                                                            */
    257   /*    cid_face_init                                                      */
    258   /*                                                                       */
    259   /* <Description>                                                         */
    260   /*    Initializes a given CID face object.                               */
    261   /*                                                                       */
    262   /* <Input>                                                               */
    263   /*    stream     :: The source font stream.                              */
    264   /*                                                                       */
    265   /*    face_index :: The index of the font face in the resource.          */
    266   /*                                                                       */
    267   /*    num_params :: Number of additional generic parameters.  Ignored.   */
    268   /*                                                                       */
    269   /*    params     :: Additional generic parameters.  Ignored.             */
    270   /*                                                                       */
    271   /* <InOut>                                                               */
    272   /*    face       :: The newly built face object.                         */
    273   /*                                                                       */
    274   /* <Return>                                                              */
    275   /*    FreeType error code.  0 means success.                             */
    276   /*                                                                       */
    277   FT_LOCAL_DEF( FT_Error )
    278   cid_face_init( FT_Stream      stream,
    279                  FT_Face        cidface,        /* CID_Face */
    280                  FT_Int         face_index,
    281                  FT_Int         num_params,
    282                  FT_Parameter*  params )
    283   {
    284     CID_Face          face = (CID_Face)cidface;
    285     FT_Error          error;
    286     PSAux_Service     psaux;
    287     PSHinter_Service  pshinter;
    288 
    289     FT_UNUSED( num_params );
    290     FT_UNUSED( params );
    291     FT_UNUSED( stream );
    292 
    293 
    294     cidface->num_faces = 1;
    295 
    296     psaux = (PSAux_Service)face->psaux;
    297     if ( !psaux )
    298     {
    299       psaux = (PSAux_Service)FT_Get_Module_Interface(
    300                 FT_FACE_LIBRARY( face ), "psaux" );
    301 
    302       if ( !psaux )
    303       {
    304         FT_ERROR(( "cid_face_init: cannot access `psaux' module\n" ));
    305         error = FT_THROW( Missing_Module );
    306         goto Exit;
    307       }
    308 
    309       face->psaux = psaux;
    310     }
    311 
    312     pshinter = (PSHinter_Service)face->pshinter;
    313     if ( !pshinter )
    314     {
    315       pshinter = (PSHinter_Service)FT_Get_Module_Interface(
    316                    FT_FACE_LIBRARY( face ), "pshinter" );
    317 
    318       face->pshinter = pshinter;
    319     }
    320 
    321     FT_TRACE2(( "CID driver\n" ));
    322 
    323     /* open the tokenizer; this will also check the font format */
    324     if ( FT_STREAM_SEEK( 0 ) )
    325       goto Exit;
    326 
    327     error = cid_face_open( face, face_index );
    328     if ( error )
    329       goto Exit;
    330 
    331     /* if we just wanted to check the format, leave successfully now */
    332     if ( face_index < 0 )
    333       goto Exit;
    334 
    335     /* check the face index */
    336     /* XXX: handle CID fonts with more than a single face */
    337     if ( ( face_index & 0xFFFF ) != 0 )
    338     {
    339       FT_ERROR(( "cid_face_init: invalid face index\n" ));
    340       error = FT_THROW( Invalid_Argument );
    341       goto Exit;
    342     }
    343 
    344     /* now load the font program into the face object */
    345 
    346     /* initialize the face object fields */
    347 
    348     /* set up root face fields */
    349     {
    350       CID_FaceInfo  cid  = &face->cid;
    351       PS_FontInfo   info = &cid->font_info;
    352 
    353 
    354       cidface->num_glyphs   = (FT_Long)cid->cid_count;
    355       cidface->num_charmaps = 0;
    356 
    357       cidface->face_index = face_index & 0xFFFF;
    358 
    359       cidface->face_flags |= FT_FACE_FLAG_SCALABLE   | /* scalable outlines */
    360                              FT_FACE_FLAG_HORIZONTAL | /* horizontal data   */
    361                              FT_FACE_FLAG_HINTER;      /* has native hinter */
    362 
    363       if ( info->is_fixed_pitch )
    364         cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
    365 
    366       /* XXX: TODO: add kerning with .afm support */
    367 
    368       /* get style name -- be careful, some broken fonts only */
    369       /* have a /FontName dictionary entry!                   */
    370       cidface->family_name = info->family_name;
    371       /* assume "Regular" style if we don't know better */
    372       cidface->style_name = (char *)"Regular";
    373       if ( cidface->family_name )
    374       {
    375         char*  full   = info->full_name;
    376         char*  family = cidface->family_name;
    377 
    378 
    379         if ( full )
    380         {
    381           while ( *full )
    382           {
    383             if ( *full == *family )
    384             {
    385               family++;
    386               full++;
    387             }
    388             else
    389             {
    390               if ( *full == ' ' || *full == '-' )
    391                 full++;
    392               else if ( *family == ' ' || *family == '-' )
    393                 family++;
    394               else
    395               {
    396                 if ( !*family )
    397                   cidface->style_name = full;
    398                 break;
    399               }
    400             }
    401           }
    402         }
    403       }
    404       else
    405       {
    406         /* do we have a `/FontName'? */
    407         if ( cid->cid_font_name )
    408           cidface->family_name = cid->cid_font_name;
    409       }
    410 
    411       /* compute style flags */
    412       cidface->style_flags = 0;
    413       if ( info->italic_angle )
    414         cidface->style_flags |= FT_STYLE_FLAG_ITALIC;
    415       if ( info->weight )
    416       {
    417         if ( !ft_strcmp( info->weight, "Bold"  ) ||
    418              !ft_strcmp( info->weight, "Black" ) )
    419           cidface->style_flags |= FT_STYLE_FLAG_BOLD;
    420       }
    421 
    422       /* no embedded bitmap support */
    423       cidface->num_fixed_sizes = 0;
    424       cidface->available_sizes = NULL;
    425 
    426       cidface->bbox.xMin =   cid->font_bbox.xMin            >> 16;
    427       cidface->bbox.yMin =   cid->font_bbox.yMin            >> 16;
    428       /* no `U' suffix here to 0xFFFF! */
    429       cidface->bbox.xMax = ( cid->font_bbox.xMax + 0xFFFF ) >> 16;
    430       cidface->bbox.yMax = ( cid->font_bbox.yMax + 0xFFFF ) >> 16;
    431 
    432       if ( !cidface->units_per_EM )
    433         cidface->units_per_EM = 1000;
    434 
    435       cidface->ascender  = (FT_Short)( cidface->bbox.yMax );
    436       cidface->descender = (FT_Short)( cidface->bbox.yMin );
    437 
    438       cidface->height = (FT_Short)( ( cidface->units_per_EM * 12 ) / 10 );
    439       if ( cidface->height < cidface->ascender - cidface->descender )
    440         cidface->height = (FT_Short)( cidface->ascender - cidface->descender );
    441 
    442       cidface->underline_position  = (FT_Short)info->underline_position;
    443       cidface->underline_thickness = (FT_Short)info->underline_thickness;
    444     }
    445 
    446   Exit:
    447     return error;
    448   }
    449 
    450 
    451   /*************************************************************************/
    452   /*                                                                       */
    453   /* <Function>                                                            */
    454   /*    cid_driver_init                                                    */
    455   /*                                                                       */
    456   /* <Description>                                                         */
    457   /*    Initializes a given CID driver object.                             */
    458   /*                                                                       */
    459   /* <Input>                                                               */
    460   /*    driver :: A handle to the target driver object.                    */
    461   /*                                                                       */
    462   /* <Return>                                                              */
    463   /*    FreeType error code.  0 means success.                             */
    464   /*                                                                       */
    465   FT_LOCAL_DEF( FT_Error )
    466   cid_driver_init( FT_Module  driver )
    467   {
    468     FT_UNUSED( driver );
    469 
    470     return FT_Err_Ok;
    471   }
    472 
    473 
    474   /*************************************************************************/
    475   /*                                                                       */
    476   /* <Function>                                                            */
    477   /*    cid_driver_done                                                    */
    478   /*                                                                       */
    479   /* <Description>                                                         */
    480   /*    Finalizes a given CID driver.                                      */
    481   /*                                                                       */
    482   /* <Input>                                                               */
    483   /*    driver :: A handle to the target CID driver.                       */
    484   /*                                                                       */
    485   FT_LOCAL_DEF( void )
    486   cid_driver_done( FT_Module  driver )
    487   {
    488     FT_UNUSED( driver );
    489   }
    490 
    491 
    492 /* END */
    493