ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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

Generated on Sat May 26 2012 04:32:59 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.