Home | History | Annotate | Download | only in type42
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  t42objs.c                                                              */
      4 /*                                                                         */
      5 /*    Type 42 objects manager (body).                                      */
      6 /*                                                                         */
      7 /*  Copyright 2002-2015 by                                                 */
      8 /*  Roberto Alameda.                                                       */
      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 "t42objs.h"
     20 #include "t42parse.h"
     21 #include "t42error.h"
     22 #include FT_INTERNAL_DEBUG_H
     23 #include FT_LIST_H
     24 #include FT_TRUETYPE_IDS_H
     25 
     26 
     27 #undef  FT_COMPONENT
     28 #define FT_COMPONENT  trace_t42
     29 
     30 
     31   static FT_Error
     32   T42_Open_Face( T42_Face  face )
     33   {
     34     T42_LoaderRec  loader;
     35     T42_Parser     parser;
     36     T1_Font        type1 = &face->type1;
     37     FT_Memory      memory = face->root.memory;
     38     FT_Error       error;
     39 
     40     PSAux_Service  psaux  = (PSAux_Service)face->psaux;
     41 
     42 
     43     t42_loader_init( &loader, face );
     44 
     45     parser = &loader.parser;
     46 
     47     if ( FT_ALLOC( face->ttf_data, 12 ) )
     48       goto Exit;
     49 
     50     /* while parsing the font we always update `face->ttf_size' so that */
     51     /* even in case of buggy data (which might lead to premature end of */
     52     /* scanning without causing an error) the call to `FT_Open_Face' in */
     53     /* `T42_Face_Init' passes the correct size                          */
     54     face->ttf_size = 12;
     55 
     56     error = t42_parser_init( parser,
     57                              face->root.stream,
     58                              memory,
     59                              psaux);
     60     if ( error )
     61       goto Exit;
     62 
     63     error = t42_parse_dict( face, &loader,
     64                             parser->base_dict, parser->base_len );
     65     if ( error )
     66       goto Exit;
     67 
     68     if ( type1->font_type != 42 )
     69     {
     70       FT_ERROR(( "T42_Open_Face: cannot handle FontType %d\n",
     71                  type1->font_type ));
     72       error = FT_THROW( Unknown_File_Format );
     73       goto Exit;
     74     }
     75 
     76     /* now, propagate the charstrings and glyphnames tables */
     77     /* to the Type1 data                                    */
     78     type1->num_glyphs = loader.num_glyphs;
     79 
     80     if ( !loader.charstrings.init )
     81     {
     82       FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" ));
     83       error = FT_THROW( Invalid_File_Format );
     84     }
     85 
     86     loader.charstrings.init  = 0;
     87     type1->charstrings_block = loader.charstrings.block;
     88     type1->charstrings       = loader.charstrings.elements;
     89     type1->charstrings_len   = loader.charstrings.lengths;
     90 
     91     /* we copy the glyph names `block' and `elements' fields; */
     92     /* the `lengths' field must be released later             */
     93     type1->glyph_names_block    = loader.glyph_names.block;
     94     type1->glyph_names          = (FT_String**)loader.glyph_names.elements;
     95     loader.glyph_names.block    = NULL;
     96     loader.glyph_names.elements = NULL;
     97 
     98     /* we must now build type1.encoding when we have a custom array */
     99     if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
    100     {
    101       FT_Int    charcode, idx, min_char, max_char;
    102       FT_Byte*  glyph_name;
    103 
    104 
    105       /* OK, we do the following: for each element in the encoding   */
    106       /* table, look up the index of the glyph having the same name  */
    107       /* as defined in the CharStrings array.                        */
    108       /* The index is then stored in type1.encoding.char_index, and  */
    109       /* the name in type1.encoding.char_name                        */
    110 
    111       min_char = 0;
    112       max_char = 0;
    113 
    114       charcode = 0;
    115       for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
    116       {
    117         FT_Byte*  char_name;
    118 
    119 
    120         type1->encoding.char_index[charcode] = 0;
    121         type1->encoding.char_name [charcode] = (char *)".notdef";
    122 
    123         char_name = loader.encoding_table.elements[charcode];
    124         if ( char_name )
    125           for ( idx = 0; idx < type1->num_glyphs; idx++ )
    126           {
    127             glyph_name = (FT_Byte*)type1->glyph_names[idx];
    128             if ( ft_strcmp( (const char*)char_name,
    129                             (const char*)glyph_name ) == 0 )
    130             {
    131               type1->encoding.char_index[charcode] = (FT_UShort)idx;
    132               type1->encoding.char_name [charcode] = (char*)glyph_name;
    133 
    134               /* Change min/max encoded char only if glyph name is */
    135               /* not /.notdef                                      */
    136               if ( ft_strcmp( (const char*)".notdef",
    137                               (const char*)glyph_name ) != 0 )
    138               {
    139                 if ( charcode < min_char )
    140                   min_char = charcode;
    141                 if ( charcode >= max_char )
    142                   max_char = charcode + 1;
    143               }
    144               break;
    145             }
    146           }
    147       }
    148 
    149       type1->encoding.code_first = min_char;
    150       type1->encoding.code_last  = max_char;
    151       type1->encoding.num_chars  = loader.num_chars;
    152     }
    153 
    154   Exit:
    155     t42_loader_done( &loader );
    156     return error;
    157   }
    158 
    159 
    160   /***************** Driver Functions *************/
    161 
    162 
    163   FT_LOCAL_DEF( FT_Error )
    164   T42_Face_Init( FT_Stream      stream,
    165                  FT_Face        t42face,       /* T42_Face */
    166                  FT_Int         face_index,
    167                  FT_Int         num_params,
    168                  FT_Parameter*  params )
    169   {
    170     T42_Face            face  = (T42_Face)t42face;
    171     FT_Error            error;
    172     FT_Service_PsCMaps  psnames;
    173     PSAux_Service       psaux;
    174     FT_Face             root  = (FT_Face)&face->root;
    175     T1_Font             type1 = &face->type1;
    176     PS_FontInfo         info  = &type1->font_info;
    177 
    178     FT_UNUSED( num_params );
    179     FT_UNUSED( params );
    180     FT_UNUSED( stream );
    181 
    182 
    183     face->ttf_face       = NULL;
    184     face->root.num_faces = 1;
    185 
    186     FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
    187     face->psnames = psnames;
    188 
    189     face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
    190                                            "psaux" );
    191     psaux = (PSAux_Service)face->psaux;
    192     if ( !psaux )
    193     {
    194       FT_ERROR(( "T42_Face_Init: cannot access `psaux' module\n" ));
    195       error = FT_THROW( Missing_Module );
    196       goto Exit;
    197     }
    198 
    199     FT_TRACE2(( "Type 42 driver\n" ));
    200 
    201     /* open the tokenizer, this will also check the font format */
    202     error = T42_Open_Face( face );
    203     if ( error )
    204       goto Exit;
    205 
    206     /* if we just wanted to check the format, leave successfully now */
    207     if ( face_index < 0 )
    208       goto Exit;
    209 
    210     /* check the face index */
    211     if ( ( face_index & 0xFFFF ) > 0 )
    212     {
    213       FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
    214       error = FT_THROW( Invalid_Argument );
    215       goto Exit;
    216     }
    217 
    218     /* Now load the font program into the face object */
    219 
    220     /* Init the face object fields */
    221     /* Now set up root face fields */
    222 
    223     root->num_glyphs   = type1->num_glyphs;
    224     root->num_charmaps = 0;
    225     root->face_index   = 0;
    226 
    227     root->face_flags |= FT_FACE_FLAG_SCALABLE    |
    228                         FT_FACE_FLAG_HORIZONTAL  |
    229                         FT_FACE_FLAG_GLYPH_NAMES;
    230 
    231     if ( info->is_fixed_pitch )
    232       root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
    233 
    234     /* We only set this flag if we have the patented bytecode interpreter. */
    235     /* There are no known `tricky' Type42 fonts that could be loaded with  */
    236     /* the unpatented interpreter.                                         */
    237 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
    238     root->face_flags |= FT_FACE_FLAG_HINTER;
    239 #endif
    240 
    241     /* XXX: TODO -- add kerning with .afm support */
    242 
    243     /* get style name -- be careful, some broken fonts only */
    244     /* have a `/FontName' dictionary entry!                 */
    245     root->family_name = info->family_name;
    246     /* assume "Regular" style if we don't know better */
    247     root->style_name = (char *)"Regular";
    248     if ( root->family_name )
    249     {
    250       char*  full   = info->full_name;
    251       char*  family = root->family_name;
    252 
    253 
    254       if ( full )
    255       {
    256         while ( *full )
    257         {
    258           if ( *full == *family )
    259           {
    260             family++;
    261             full++;
    262           }
    263           else
    264           {
    265             if ( *full == ' ' || *full == '-' )
    266               full++;
    267             else if ( *family == ' ' || *family == '-' )
    268               family++;
    269             else
    270             {
    271               if ( !*family )
    272                 root->style_name = full;
    273               break;
    274             }
    275           }
    276         }
    277       }
    278     }
    279     else
    280     {
    281       /* do we have a `/FontName'? */
    282       if ( type1->font_name )
    283         root->family_name = type1->font_name;
    284     }
    285 
    286     /* no embedded bitmap support */
    287     root->num_fixed_sizes = 0;
    288     root->available_sizes = NULL;
    289 
    290     /* Load the TTF font embedded in the T42 font */
    291     {
    292       FT_Open_Args  args;
    293 
    294 
    295       args.flags       = FT_OPEN_MEMORY | FT_OPEN_DRIVER;
    296       args.driver      = FT_Get_Module( FT_FACE_LIBRARY( face ),
    297                                         "truetype" );
    298       args.memory_base = face->ttf_data;
    299       args.memory_size = face->ttf_size;
    300 
    301       if ( num_params )
    302       {
    303         args.flags     |= FT_OPEN_PARAMS;
    304         args.num_params = num_params;
    305         args.params     = params;
    306       }
    307 
    308       error = FT_Open_Face( FT_FACE_LIBRARY( face ),
    309                             &args, 0, &face->ttf_face );
    310     }
    311 
    312     if ( error )
    313       goto Exit;
    314 
    315     FT_Done_Size( face->ttf_face->size );
    316 
    317     /* Ignore info in FontInfo dictionary and use the info from the  */
    318     /* loaded TTF font.  The PostScript interpreter also ignores it. */
    319     root->bbox         = face->ttf_face->bbox;
    320     root->units_per_EM = face->ttf_face->units_per_EM;
    321 
    322     root->ascender  = face->ttf_face->ascender;
    323     root->descender = face->ttf_face->descender;
    324     root->height    = face->ttf_face->height;
    325 
    326     root->max_advance_width  = face->ttf_face->max_advance_width;
    327     root->max_advance_height = face->ttf_face->max_advance_height;
    328 
    329     root->underline_position  = (FT_Short)info->underline_position;
    330     root->underline_thickness = (FT_Short)info->underline_thickness;
    331 
    332     /* compute style flags */
    333     root->style_flags = 0;
    334     if ( info->italic_angle )
    335       root->style_flags |= FT_STYLE_FLAG_ITALIC;
    336 
    337     if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
    338       root->style_flags |= FT_STYLE_FLAG_BOLD;
    339 
    340     if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
    341       root->face_flags |= FT_FACE_FLAG_VERTICAL;
    342 
    343     {
    344       if ( psnames )
    345       {
    346         FT_CharMapRec    charmap;
    347         T1_CMap_Classes  cmap_classes = psaux->t1_cmap_classes;
    348         FT_CMap_Class    clazz;
    349 
    350 
    351         charmap.face = root;
    352 
    353         /* first of all, try to synthesize a Unicode charmap */
    354         charmap.platform_id = TT_PLATFORM_MICROSOFT;
    355         charmap.encoding_id = TT_MS_ID_UNICODE_CS;
    356         charmap.encoding    = FT_ENCODING_UNICODE;
    357 
    358         error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
    359         if ( error                                      &&
    360              FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
    361           goto Exit;
    362         error = FT_Err_Ok;
    363 
    364         /* now, generate an Adobe Standard encoding when appropriate */
    365         charmap.platform_id = TT_PLATFORM_ADOBE;
    366         clazz               = NULL;
    367 
    368         switch ( type1->encoding_type )
    369         {
    370         case T1_ENCODING_TYPE_STANDARD:
    371           charmap.encoding    = FT_ENCODING_ADOBE_STANDARD;
    372           charmap.encoding_id = TT_ADOBE_ID_STANDARD;
    373           clazz               = cmap_classes->standard;
    374           break;
    375 
    376         case T1_ENCODING_TYPE_EXPERT:
    377           charmap.encoding    = FT_ENCODING_ADOBE_EXPERT;
    378           charmap.encoding_id = TT_ADOBE_ID_EXPERT;
    379           clazz               = cmap_classes->expert;
    380           break;
    381 
    382         case T1_ENCODING_TYPE_ARRAY:
    383           charmap.encoding    = FT_ENCODING_ADOBE_CUSTOM;
    384           charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
    385           clazz               = cmap_classes->custom;
    386           break;
    387 
    388         case T1_ENCODING_TYPE_ISOLATIN1:
    389           charmap.encoding    = FT_ENCODING_ADOBE_LATIN_1;
    390           charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
    391           clazz               = cmap_classes->unicode;
    392           break;
    393 
    394         default:
    395           ;
    396         }
    397 
    398         if ( clazz )
    399           error = FT_CMap_New( clazz, NULL, &charmap, NULL );
    400 
    401 #if 0
    402         /* Select default charmap */
    403         if ( root->num_charmaps )
    404           root->charmap = root->charmaps[0];
    405 #endif
    406       }
    407     }
    408   Exit:
    409     return error;
    410   }
    411 
    412 
    413   FT_LOCAL_DEF( void )
    414   T42_Face_Done( FT_Face  t42face )
    415   {
    416     T42_Face     face = (T42_Face)t42face;
    417     T1_Font      type1;
    418     PS_FontInfo  info;
    419     FT_Memory    memory;
    420 
    421 
    422     if ( !face )
    423       return;
    424 
    425     type1  = &face->type1;
    426     info   = &type1->font_info;
    427     memory = face->root.memory;
    428 
    429     /* delete internal ttf face prior to freeing face->ttf_data */
    430     if ( face->ttf_face )
    431       FT_Done_Face( face->ttf_face );
    432 
    433     /* release font info strings */
    434     FT_FREE( info->version );
    435     FT_FREE( info->notice );
    436     FT_FREE( info->full_name );
    437     FT_FREE( info->family_name );
    438     FT_FREE( info->weight );
    439 
    440     /* release top dictionary */
    441     FT_FREE( type1->charstrings_len );
    442     FT_FREE( type1->charstrings );
    443     FT_FREE( type1->glyph_names );
    444 
    445     FT_FREE( type1->charstrings_block );
    446     FT_FREE( type1->glyph_names_block );
    447 
    448     FT_FREE( type1->encoding.char_index );
    449     FT_FREE( type1->encoding.char_name );
    450     FT_FREE( type1->font_name );
    451 
    452     FT_FREE( face->ttf_data );
    453 
    454 #if 0
    455     /* release afm data if present */
    456     if ( face->afm_data )
    457       T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
    458 #endif
    459 
    460     /* release unicode map, if any */
    461     FT_FREE( face->unicode_map.maps );
    462     face->unicode_map.num_maps = 0;
    463 
    464     face->root.family_name = NULL;
    465     face->root.style_name  = NULL;
    466   }
    467 
    468 
    469   /*************************************************************************/
    470   /*                                                                       */
    471   /* <Function>                                                            */
    472   /*    T42_Driver_Init                                                    */
    473   /*                                                                       */
    474   /* <Description>                                                         */
    475   /*    Initializes a given Type 42 driver object.                         */
    476   /*                                                                       */
    477   /* <Input>                                                               */
    478   /*    driver :: A handle to the target driver object.                    */
    479   /*                                                                       */
    480   /* <Return>                                                              */
    481   /*    FreeType error code.  0 means success.                             */
    482   /*                                                                       */
    483   FT_LOCAL_DEF( FT_Error )
    484   T42_Driver_Init( FT_Module  module )        /* T42_Driver */
    485   {
    486     T42_Driver  driver = (T42_Driver)module;
    487     FT_Module   ttmodule;
    488 
    489 
    490     ttmodule = FT_Get_Module( module->library, "truetype" );
    491     if ( !ttmodule )
    492     {
    493       FT_ERROR(( "T42_Driver_Init: cannot access `truetype' module\n" ));
    494       return FT_THROW( Missing_Module );
    495     }
    496 
    497     driver->ttclazz = (FT_Driver_Class)ttmodule->clazz;
    498 
    499     return FT_Err_Ok;
    500   }
    501 
    502 
    503   FT_LOCAL_DEF( void )
    504   T42_Driver_Done( FT_Module  module )
    505   {
    506     FT_UNUSED( module );
    507   }
    508 
    509 
    510   FT_LOCAL_DEF( FT_Error )
    511   T42_Size_Init( FT_Size  size )         /* T42_Size */
    512   {
    513     T42_Size  t42size = (T42_Size)size;
    514     FT_Face   face    = size->face;
    515     T42_Face  t42face = (T42_Face)face;
    516     FT_Size   ttsize;
    517     FT_Error  error;
    518 
    519 
    520     error = FT_New_Size( t42face->ttf_face, &ttsize );
    521     t42size->ttsize = ttsize;
    522 
    523     FT_Activate_Size( ttsize );
    524 
    525     return error;
    526   }
    527 
    528 
    529   FT_LOCAL_DEF( FT_Error )
    530   T42_Size_Request( FT_Size          t42size,      /* T42_Size */
    531                     FT_Size_Request  req )
    532   {
    533     T42_Size  size = (T42_Size)t42size;
    534     T42_Face  face = (T42_Face)t42size->face;
    535     FT_Error  error;
    536 
    537 
    538     FT_Activate_Size( size->ttsize );
    539 
    540     error = FT_Request_Size( face->ttf_face, req );
    541     if ( !error )
    542       t42size->metrics = face->ttf_face->size->metrics;
    543 
    544     return error;
    545   }
    546 
    547 
    548   FT_LOCAL_DEF( FT_Error )
    549   T42_Size_Select( FT_Size   t42size,         /* T42_Size */
    550                    FT_ULong  strike_index )
    551   {
    552     T42_Size  size = (T42_Size)t42size;
    553     T42_Face  face = (T42_Face)t42size->face;
    554     FT_Error  error;
    555 
    556 
    557     FT_Activate_Size( size->ttsize );
    558 
    559     error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
    560     if ( !error )
    561       t42size->metrics = face->ttf_face->size->metrics;
    562 
    563     return error;
    564 
    565   }
    566 
    567 
    568   FT_LOCAL_DEF( void )
    569   T42_Size_Done( FT_Size  t42size )             /* T42_Size */
    570   {
    571     T42_Size     size    = (T42_Size)t42size;
    572     FT_Face      face    = t42size->face;
    573     T42_Face     t42face = (T42_Face)face;
    574     FT_ListNode  node;
    575 
    576 
    577     node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
    578     if ( node )
    579     {
    580       FT_Done_Size( size->ttsize );
    581       size->ttsize = NULL;
    582     }
    583   }
    584 
    585 
    586   FT_LOCAL_DEF( FT_Error )
    587   T42_GlyphSlot_Init( FT_GlyphSlot  t42slot )        /* T42_GlyphSlot */
    588   {
    589     T42_GlyphSlot  slot    = (T42_GlyphSlot)t42slot;
    590     FT_Face        face    = t42slot->face;
    591     T42_Face       t42face = (T42_Face)face;
    592     FT_GlyphSlot   ttslot;
    593     FT_Error       error   = FT_Err_Ok;
    594 
    595 
    596     if ( face->glyph == NULL )
    597     {
    598       /* First glyph slot for this face */
    599       slot->ttslot = t42face->ttf_face->glyph;
    600     }
    601     else
    602     {
    603       error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );
    604       slot->ttslot = ttslot;
    605     }
    606 
    607     return error;
    608   }
    609 
    610 
    611   FT_LOCAL_DEF( void )
    612   T42_GlyphSlot_Done( FT_GlyphSlot  t42slot )       /* T42_GlyphSlot */
    613   {
    614     T42_GlyphSlot  slot = (T42_GlyphSlot)t42slot;
    615 
    616 
    617     FT_Done_GlyphSlot( slot->ttslot );
    618   }
    619 
    620 
    621   static void
    622   t42_glyphslot_clear( FT_GlyphSlot  slot )
    623   {
    624     /* free bitmap if needed */
    625     ft_glyphslot_free_bitmap( slot );
    626 
    627     /* clear all public fields in the glyph slot */
    628     FT_ZERO( &slot->metrics );
    629     FT_ZERO( &slot->outline );
    630     FT_ZERO( &slot->bitmap );
    631 
    632     slot->bitmap_left   = 0;
    633     slot->bitmap_top    = 0;
    634     slot->num_subglyphs = 0;
    635     slot->subglyphs     = NULL;
    636     slot->control_data  = NULL;
    637     slot->control_len   = 0;
    638     slot->other         = NULL;
    639     slot->format        = FT_GLYPH_FORMAT_NONE;
    640 
    641     slot->linearHoriAdvance = 0;
    642     slot->linearVertAdvance = 0;
    643   }
    644 
    645 
    646   FT_LOCAL_DEF( FT_Error )
    647   T42_GlyphSlot_Load( FT_GlyphSlot  glyph,
    648                       FT_Size       size,
    649                       FT_UInt       glyph_index,
    650                       FT_Int32      load_flags )
    651   {
    652     FT_Error         error;
    653     T42_GlyphSlot    t42slot = (T42_GlyphSlot)glyph;
    654     T42_Size         t42size = (T42_Size)size;
    655     T42_Face         t42face = (T42_Face)size->face;
    656     FT_Driver_Class  ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;
    657 
    658 
    659     FT_TRACE1(( "T42_GlyphSlot_Load: glyph index %d\n", glyph_index ));
    660 
    661     /* map T42 glyph index to embedded TTF's glyph index */
    662     glyph_index = (FT_UInt)ft_atol(
    663                     (const char *)t42face->type1.charstrings[glyph_index] );
    664 
    665     t42_glyphslot_clear( t42slot->ttslot );
    666     error = ttclazz->load_glyph( t42slot->ttslot,
    667                                  t42size->ttsize,
    668                                  glyph_index,
    669                                  load_flags | FT_LOAD_NO_BITMAP );
    670 
    671     if ( !error )
    672     {
    673       glyph->metrics = t42slot->ttslot->metrics;
    674 
    675       glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;
    676       glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;
    677 
    678       glyph->format  = t42slot->ttslot->format;
    679       glyph->outline = t42slot->ttslot->outline;
    680 
    681       glyph->bitmap      = t42slot->ttslot->bitmap;
    682       glyph->bitmap_left = t42slot->ttslot->bitmap_left;
    683       glyph->bitmap_top  = t42slot->ttslot->bitmap_top;
    684 
    685       glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;
    686       glyph->subglyphs     = t42slot->ttslot->subglyphs;
    687 
    688       glyph->control_data  = t42slot->ttslot->control_data;
    689       glyph->control_len   = t42slot->ttslot->control_len;
    690     }
    691 
    692     return error;
    693   }
    694 
    695 
    696 /* END */
    697