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