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

ttpost.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttpost.c                                                               */
00004 /*                                                                         */
00005 /*    Postcript name table processing for TrueType and OpenType fonts      */
00006 /*    (body).                                                              */
00007 /*                                                                         */
00008 /*  Copyright 1996-2001, 2002, 2003, 2006, 2007, 2008, 2009, 2010 by       */
00009 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00010 /*                                                                         */
00011 /*  This file is part of the FreeType project, and may only be used,       */
00012 /*  modified, and distributed under the terms of the FreeType project      */
00013 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00014 /*  this file you indicate that you have read the license and              */
00015 /*  understand and accept it fully.                                        */
00016 /*                                                                         */
00017 /***************************************************************************/
00018 
00019   /*************************************************************************/
00020   /*                                                                       */
00021   /* The post table is not completely loaded by the core engine.  This     */
00022   /* file loads the missing PS glyph names and implements an API to access */
00023   /* them.                                                                 */
00024   /*                                                                       */
00025   /*************************************************************************/
00026 
00027 
00028 #include <ft2build.h>
00029 #include FT_INTERNAL_DEBUG_H
00030 #include FT_INTERNAL_STREAM_H
00031 #include FT_TRUETYPE_TAGS_H
00032 #include "ttpost.h"
00033 
00034 #include "sferrors.h"
00035 
00036 
00037   /*************************************************************************/
00038   /*                                                                       */
00039   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00040   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00041   /* messages during execution.                                            */
00042   /*                                                                       */
00043 #undef  FT_COMPONENT
00044 #define FT_COMPONENT  trace_ttpost
00045 
00046 
00047   /* If this configuration macro is defined, we rely on the `PSNames' */
00048   /* module to grab the glyph names.                                  */
00049 
00050 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
00051 
00052 
00053 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00054 
00055 #define MAC_NAME( x )  ( (FT_String*)psnames->macintosh_name( x ) )
00056 
00057 
00058 #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
00059 
00060 
00061    /* Otherwise, we ignore the `PSNames' module, and provide our own  */
00062    /* table of Mac names.  Thus, it is possible to build a version of */
00063    /* FreeType without the Type 1 driver & PSNames module.            */
00064 
00065 #define MAC_NAME( x )  ( (FT_String*)tt_post_default_names[x] )
00066 
00067   /* the 258 default Mac PS glyph names */
00068 
00069   static const FT_String* const  tt_post_default_names[258] =
00070   {
00071     /*   0 */
00072     ".notdef", ".null", "CR", "space", "exclam",
00073     "quotedbl", "numbersign", "dollar", "percent", "ampersand",
00074     /*  10 */
00075     "quotesingle", "parenleft", "parenright", "asterisk", "plus",
00076     "comma", "hyphen", "period", "slash", "zero",
00077     /*  20 */
00078     "one", "two", "three", "four", "five",
00079     "six", "seven", "eight", "nine", "colon",
00080     /*  30 */
00081     "semicolon", "less", "equal", "greater", "question",
00082     "at", "A", "B", "C", "D",
00083     /*  40 */
00084     "E", "F", "G", "H", "I",
00085     "J", "K", "L", "M", "N",
00086     /*  50 */
00087     "O", "P", "Q", "R", "S",
00088     "T", "U", "V", "W", "X",
00089     /*  60 */
00090     "Y", "Z", "bracketleft", "backslash", "bracketright",
00091     "asciicircum", "underscore", "grave", "a", "b",
00092     /*  70 */
00093     "c", "d", "e", "f", "g",
00094     "h", "i", "j", "k", "l",
00095     /*  80 */
00096     "m", "n", "o", "p", "q",
00097     "r", "s", "t", "u", "v",
00098     /*  90 */
00099     "w", "x", "y", "z", "braceleft",
00100     "bar", "braceright", "asciitilde", "Adieresis", "Aring",
00101     /* 100 */
00102     "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
00103     "aacute", "agrave", "acircumflex", "adieresis", "atilde",
00104     /* 110 */
00105     "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
00106     "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
00107     /* 120 */
00108     "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
00109     "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
00110     /* 130 */
00111     "dagger", "degree", "cent", "sterling", "section",
00112     "bullet", "paragraph", "germandbls", "registered", "copyright",
00113     /* 140 */
00114     "trademark", "acute", "dieresis", "notequal", "AE",
00115     "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
00116     /* 150 */
00117     "yen", "mu", "partialdiff", "summation", "product",
00118     "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
00119     /* 160 */
00120     "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
00121     "radical", "florin", "approxequal", "Delta", "guillemotleft",
00122     /* 170 */
00123     "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",
00124     "Otilde", "OE", "oe", "endash", "emdash",
00125     /* 180 */
00126     "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
00127     "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
00128     /* 190 */
00129     "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
00130     "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
00131     /* 200 */
00132     "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
00133     "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
00134     /* 210 */
00135     "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
00136     "dotlessi", "circumflex", "tilde", "macron", "breve",
00137     /* 220 */
00138     "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
00139     "caron", "Lslash", "lslash", "Scaron", "scaron",
00140     /* 230 */
00141     "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
00142     "Yacute", "yacute", "Thorn", "thorn", "minus",
00143     /* 240 */
00144     "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
00145     "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
00146     /* 250 */
00147     "Idot", "Scedilla", "scedilla", "Cacute", "cacute",
00148     "Ccaron", "ccaron", "dmacron",
00149   };
00150 
00151 
00152 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
00153 
00154 
00155   static FT_Error
00156   load_format_20( TT_Face    face,
00157                   FT_Stream  stream,
00158                   FT_Long    post_limit )
00159   {
00160     FT_Memory   memory = stream->memory;
00161     FT_Error    error;
00162 
00163     FT_Int      num_glyphs;
00164     FT_UShort   num_names;
00165 
00166     FT_UShort*  glyph_indices = 0;
00167     FT_Char**   name_strings  = 0;
00168 
00169 
00170     if ( FT_READ_USHORT( num_glyphs ) )
00171       goto Exit;
00172 
00173     /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
00174     /* than the value in the maxp table (cf. cyberbit.ttf).             */
00175 
00176     /* There already exist fonts which have more than 32768 glyph names */
00177     /* in this table, so the test for this threshold has been dropped.  */
00178 
00179     if ( num_glyphs > face->max_profile.numGlyphs )
00180     {
00181       error = SFNT_Err_Invalid_File_Format;
00182       goto Exit;
00183     }
00184 
00185     /* load the indices */
00186     {
00187       FT_Int  n;
00188 
00189 
00190       if ( FT_NEW_ARRAY ( glyph_indices, num_glyphs ) ||
00191            FT_FRAME_ENTER( num_glyphs * 2L )          )
00192         goto Fail;
00193 
00194       for ( n = 0; n < num_glyphs; n++ )
00195         glyph_indices[n] = FT_GET_USHORT();
00196 
00197       FT_FRAME_EXIT();
00198     }
00199 
00200     /* compute number of names stored in table */
00201     {
00202       FT_Int  n;
00203 
00204 
00205       num_names = 0;
00206 
00207       for ( n = 0; n < num_glyphs; n++ )
00208       {
00209         FT_Int  idx;
00210 
00211 
00212         idx = glyph_indices[n];
00213         if ( idx >= 258 )
00214         {
00215           idx -= 257;
00216           if ( idx > num_names )
00217             num_names = (FT_UShort)idx;
00218         }
00219       }
00220     }
00221 
00222     /* now load the name strings */
00223     {
00224       FT_UShort  n;
00225 
00226 
00227       if ( FT_NEW_ARRAY( name_strings, num_names ) )
00228         goto Fail;
00229 
00230       for ( n = 0; n < num_names; n++ )
00231       {
00232         FT_UInt  len;
00233 
00234 
00235         if ( FT_STREAM_POS() >= post_limit )
00236           break;
00237         else
00238         {
00239           FT_TRACE6(( "load_format_20: %d byte left in post table\n",
00240                       post_limit - FT_STREAM_POS() ));
00241 
00242           if ( FT_READ_BYTE( len ) )
00243             goto Fail1;
00244         }
00245 
00246         if ( (FT_Int)len > post_limit                   ||
00247              FT_STREAM_POS() > post_limit - (FT_Int)len )
00248         {
00249           FT_ERROR(( "load_format_20:"
00250                      " exceeding string length (%d),"
00251                      " truncating at end of post table (%d byte left)\n",
00252                      len, post_limit - FT_STREAM_POS() ));
00253           len = FT_MAX( 0, post_limit - FT_STREAM_POS() );
00254         }
00255 
00256         if ( FT_NEW_ARRAY( name_strings[n], len + 1 ) ||
00257              FT_STREAM_READ( name_strings[n], len   ) )
00258           goto Fail1;
00259 
00260         name_strings[n][len] = '\0';
00261       }
00262 
00263       if ( n < num_names )
00264       {
00265         FT_ERROR(( "load_format_20:"
00266                    " all entries in post table are already parsed,"
00267                    " using NULL names for gid %d - %d\n",
00268                     n, num_names - 1 ));
00269         for ( ; n < num_names; n++ )
00270           if ( FT_NEW_ARRAY( name_strings[n], 1 ) )
00271             goto Fail1;
00272           else
00273             name_strings[n][0] = '\0';
00274       }
00275     }
00276 
00277     /* all right, set table fields and exit successfully */
00278     {
00279       TT_Post_20  table = &face->postscript_names.names.format_20;
00280 
00281 
00282       table->num_glyphs    = (FT_UShort)num_glyphs;
00283       table->num_names     = (FT_UShort)num_names;
00284       table->glyph_indices = glyph_indices;
00285       table->glyph_names   = name_strings;
00286     }
00287     return SFNT_Err_Ok;
00288 
00289   Fail1:
00290     {
00291       FT_UShort  n;
00292 
00293 
00294       for ( n = 0; n < num_names; n++ )
00295         FT_FREE( name_strings[n] );
00296     }
00297 
00298   Fail:
00299     FT_FREE( name_strings );
00300     FT_FREE( glyph_indices );
00301 
00302   Exit:
00303     return error;
00304   }
00305 
00306 
00307   static FT_Error
00308   load_format_25( TT_Face    face,
00309                   FT_Stream  stream,
00310                   FT_Long    post_limit )
00311   {
00312     FT_Memory  memory = stream->memory;
00313     FT_Error   error;
00314 
00315     FT_Int     num_glyphs;
00316     FT_Char*   offset_table = 0;
00317 
00318     FT_UNUSED( post_limit );
00319 
00320 
00321     /* UNDOCUMENTED!  This value appears only in the Apple TT specs. */
00322     if ( FT_READ_USHORT( num_glyphs ) )
00323       goto Exit;
00324 
00325     /* check the number of glyphs */
00326     if ( num_glyphs > face->max_profile.numGlyphs || num_glyphs > 258 )
00327     {
00328       error = SFNT_Err_Invalid_File_Format;
00329       goto Exit;
00330     }
00331 
00332     if ( FT_NEW_ARRAY( offset_table, num_glyphs )   ||
00333          FT_STREAM_READ( offset_table, num_glyphs ) )
00334       goto Fail;
00335 
00336     /* now check the offset table */
00337     {
00338       FT_Int  n;
00339 
00340 
00341       for ( n = 0; n < num_glyphs; n++ )
00342       {
00343         FT_Long  idx = (FT_Long)n + offset_table[n];
00344 
00345 
00346         if ( idx < 0 || idx > num_glyphs )
00347         {
00348           error = SFNT_Err_Invalid_File_Format;
00349           goto Fail;
00350         }
00351       }
00352     }
00353 
00354     /* OK, set table fields and exit successfully */
00355     {
00356       TT_Post_25  table = &face->postscript_names.names.format_25;
00357 
00358 
00359       table->num_glyphs = (FT_UShort)num_glyphs;
00360       table->offsets    = offset_table;
00361     }
00362 
00363     return SFNT_Err_Ok;
00364 
00365   Fail:
00366     FT_FREE( offset_table );
00367 
00368   Exit:
00369     return error;
00370   }
00371 
00372 
00373   static FT_Error
00374   load_post_names( TT_Face  face )
00375   {
00376     FT_Stream  stream;
00377     FT_Error   error;
00378     FT_Fixed   format;
00379     FT_ULong   post_len;
00380     FT_Long    post_limit;
00381 
00382 
00383     /* get a stream for the face's resource */
00384     stream = face->root.stream;
00385 
00386     /* seek to the beginning of the PS names table */
00387     error = face->goto_table( face, TTAG_post, stream, &post_len );
00388     if ( error )
00389       goto Exit;
00390 
00391     post_limit = FT_STREAM_POS() + post_len;
00392 
00393     format = face->postscript.FormatType;
00394 
00395     /* go to beginning of subtable */
00396     if ( FT_STREAM_SKIP( 32 ) )
00397       goto Exit;
00398 
00399     /* now read postscript table */
00400     if ( format == 0x00020000L )
00401       error = load_format_20( face, stream, post_limit );
00402     else if ( format == 0x00028000L )
00403       error = load_format_25( face, stream, post_limit );
00404     else
00405       error = SFNT_Err_Invalid_File_Format;
00406 
00407     face->postscript_names.loaded = 1;
00408 
00409   Exit:
00410     return error;
00411   }
00412 
00413 
00414   FT_LOCAL_DEF( void )
00415   tt_face_free_ps_names( TT_Face  face )
00416   {
00417     FT_Memory      memory = face->root.memory;
00418     TT_Post_Names  names  = &face->postscript_names;
00419     FT_Fixed       format;
00420 
00421 
00422     if ( names->loaded )
00423     {
00424       format = face->postscript.FormatType;
00425 
00426       if ( format == 0x00020000L )
00427       {
00428         TT_Post_20  table = &names->names.format_20;
00429         FT_UShort   n;
00430 
00431 
00432         FT_FREE( table->glyph_indices );
00433         table->num_glyphs = 0;
00434 
00435         for ( n = 0; n < table->num_names; n++ )
00436           FT_FREE( table->glyph_names[n] );
00437 
00438         FT_FREE( table->glyph_names );
00439         table->num_names = 0;
00440       }
00441       else if ( format == 0x00028000L )
00442       {
00443         TT_Post_25  table = &names->names.format_25;
00444 
00445 
00446         FT_FREE( table->offsets );
00447         table->num_glyphs = 0;
00448       }
00449     }
00450     names->loaded = 0;
00451   }
00452 
00453 
00454   /*************************************************************************/
00455   /*                                                                       */
00456   /* <Function>                                                            */
00457   /*    tt_face_get_ps_name                                                */
00458   /*                                                                       */
00459   /* <Description>                                                         */
00460   /*    Get the PostScript glyph name of a glyph.                          */
00461   /*                                                                       */
00462   /* <Input>                                                               */
00463   /*    face   :: A handle to the parent face.                             */
00464   /*                                                                       */
00465   /*    idx    :: The glyph index.                                         */
00466   /*                                                                       */
00467   /* <InOut>                                                               */
00468   /*    PSname :: The address of a string pointer.  Will be NULL in case   */
00469   /*              of error, otherwise it is a pointer to the glyph name.   */
00470   /*                                                                       */
00471   /*              You must not modify the returned string!                 */
00472   /*                                                                       */
00473   /* <Output>                                                              */
00474   /*    FreeType error code.  0 means success.                             */
00475   /*                                                                       */
00476   FT_LOCAL_DEF( FT_Error )
00477   tt_face_get_ps_name( TT_Face      face,
00478                        FT_UInt      idx,
00479                        FT_String**  PSname )
00480   {
00481     FT_Error       error;
00482     TT_Post_Names  names;
00483     FT_Fixed       format;
00484 
00485 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
00486     FT_Service_PsCMaps  psnames;
00487 #endif
00488 
00489 
00490     if ( !face )
00491       return SFNT_Err_Invalid_Face_Handle;
00492 
00493     if ( idx >= (FT_UInt)face->max_profile.numGlyphs )
00494       return SFNT_Err_Invalid_Glyph_Index;
00495 
00496 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
00497     psnames = (FT_Service_PsCMaps)face->psnames;
00498     if ( !psnames )
00499       return SFNT_Err_Unimplemented_Feature;
00500 #endif
00501 
00502     names = &face->postscript_names;
00503 
00504     /* `.notdef' by default */
00505     *PSname = MAC_NAME( 0 );
00506 
00507     format = face->postscript.FormatType;
00508 
00509     if ( format == 0x00010000L )
00510     {
00511       if ( idx < 258 )                    /* paranoid checking */
00512         *PSname = MAC_NAME( idx );
00513     }
00514     else if ( format == 0x00020000L )
00515     {
00516       TT_Post_20  table = &names->names.format_20;
00517 
00518 
00519       if ( !names->loaded )
00520       {
00521         error = load_post_names( face );
00522         if ( error )
00523           goto End;
00524       }
00525 
00526       if ( idx < (FT_UInt)table->num_glyphs )
00527       {
00528         FT_UShort  name_index = table->glyph_indices[idx];
00529 
00530 
00531         if ( name_index < 258 )
00532           *PSname = MAC_NAME( name_index );
00533         else
00534           *PSname = (FT_String*)table->glyph_names[name_index - 258];
00535       }
00536     }
00537     else if ( format == 0x00028000L )
00538     {
00539       TT_Post_25  table = &names->names.format_25;
00540 
00541 
00542       if ( !names->loaded )
00543       {
00544         error = load_post_names( face );
00545         if ( error )
00546           goto End;
00547       }
00548 
00549       if ( idx < (FT_UInt)table->num_glyphs )    /* paranoid checking */
00550       {
00551         idx    += table->offsets[idx];
00552         *PSname = MAC_NAME( idx );
00553       }
00554     }
00555 
00556     /* nothing to do for format == 0x00030000L */
00557 
00558   End:
00559     return SFNT_Err_Ok;
00560   }
00561 
00562 
00563 /* END */

Generated on Sun May 27 2012 04:34:02 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.