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

ttpload.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  ttpload.c                                                              */
00004 /*                                                                         */
00005 /*    TrueType-specific tables loader (body).                              */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
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 <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_OBJECTS_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_TRUETYPE_TAGS_H
00024 
00025 #include "ttpload.h"
00026 
00027 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
00028 #include "ttgxvar.h"
00029 #endif
00030 
00031 #include "tterrors.h"
00032 
00033 
00034   /*************************************************************************/
00035   /*                                                                       */
00036   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00037   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00038   /* messages during execution.                                            */
00039   /*                                                                       */
00040 #undef  FT_COMPONENT
00041 #define FT_COMPONENT  trace_ttpload
00042 
00043 
00044   /*************************************************************************/
00045   /*                                                                       */
00046   /* <Function>                                                            */
00047   /*    tt_face_load_loca                                                  */
00048   /*                                                                       */
00049   /* <Description>                                                         */
00050   /*    Load the locations table.                                          */
00051   /*                                                                       */
00052   /* <InOut>                                                               */
00053   /*    face   :: A handle to the target face object.                      */
00054   /*                                                                       */
00055   /* <Input>                                                               */
00056   /*    stream :: The input stream.                                        */
00057   /*                                                                       */
00058   /* <Return>                                                              */
00059   /*    FreeType error code.  0 means success.                             */
00060   /*                                                                       */
00061   FT_LOCAL_DEF( FT_Error )
00062   tt_face_load_loca( TT_Face    face,
00063                      FT_Stream  stream )
00064   {
00065     FT_Error  error;
00066     FT_ULong  table_len;
00067     FT_Int    shift;
00068 
00069 
00070     /* we need the size of the `glyf' table for malformed `loca' tables */
00071     error = face->goto_table( face, TTAG_glyf, stream, &face->glyf_len );
00072 
00073     /* it is possible that a font doesn't have a glyf table at all */
00074     /* or its size is zero                                         */
00075     if ( error == TT_Err_Table_Missing )
00076       face->glyf_len = 0;
00077     else if ( error )
00078       goto Exit;
00079 
00080     FT_TRACE2(( "Locations " ));
00081     error = face->goto_table( face, TTAG_loca, stream, &table_len );
00082     if ( error )
00083     {
00084       error = TT_Err_Locations_Missing;
00085       goto Exit;
00086     }
00087 
00088     if ( face->header.Index_To_Loc_Format != 0 )
00089     {
00090       shift = 2;
00091 
00092       if ( table_len >= 0x40000L )
00093       {
00094         FT_TRACE2(( "table too large\n" ));
00095         error = TT_Err_Invalid_Table;
00096         goto Exit;
00097       }
00098       face->num_locations = table_len >> shift;
00099     }
00100     else
00101     {
00102       shift = 1;
00103 
00104       if ( table_len >= 0x20000L )
00105       {
00106         FT_TRACE2(( "table too large\n" ));
00107         error = TT_Err_Invalid_Table;
00108         goto Exit;
00109       }
00110       face->num_locations = table_len >> shift;
00111     }
00112 
00113     if ( face->num_locations != (FT_ULong)face->root.num_glyphs )
00114     {
00115       FT_TRACE2(( "glyph count mismatch!  loca: %d, maxp: %d\n",
00116                   face->num_locations, face->root.num_glyphs ));
00117 
00118       /* we only handle the case where `maxp' gives a larger value */
00119       if ( face->num_locations < (FT_ULong)face->root.num_glyphs )
00120       {
00121         FT_Long   new_loca_len = (FT_Long)face->root.num_glyphs << shift;
00122 
00123         TT_Table  entry = face->dir_tables;
00124         TT_Table  limit = entry + face->num_tables;
00125 
00126         FT_Long   pos  = FT_Stream_Pos( stream );
00127         FT_Long   dist = 0x7FFFFFFFL;
00128 
00129 
00130         /* compute the distance to next table in font file */
00131         for ( ; entry < limit; entry++ )
00132         {
00133           FT_Long  diff = entry->Offset - pos;
00134 
00135 
00136           if ( diff > 0 && diff < dist )
00137             dist = diff;
00138         }
00139 
00140         if ( entry == limit )
00141         {
00142           /* `loca' is the last table */
00143           dist = stream->size - pos;
00144         }
00145 
00146         if ( new_loca_len <= dist )
00147         {
00148           face->num_locations = face->root.num_glyphs;
00149           table_len           = new_loca_len;
00150 
00151           FT_TRACE2(( "adjusting num_locations to %d\n",
00152                       face->num_locations ));
00153         }
00154       }
00155     }
00156 
00157     /*
00158      * Extract the frame.  We don't need to decompress it since
00159      * we are able to parse it directly.
00160      */
00161     if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
00162       goto Exit;
00163 
00164     FT_TRACE2(( "loaded\n" ));
00165 
00166   Exit:
00167     return error;
00168   }
00169 
00170 
00171   FT_LOCAL_DEF( FT_ULong )
00172   tt_face_get_location( TT_Face   face,
00173                         FT_UInt   gindex,
00174                         FT_UInt  *asize )
00175   {
00176     FT_ULong  pos1, pos2;
00177     FT_Byte*  p;
00178     FT_Byte*  p_limit;
00179 
00180 
00181     pos1 = pos2 = 0;
00182 
00183     if ( gindex < face->num_locations )
00184     {
00185       if ( face->header.Index_To_Loc_Format != 0 )
00186       {
00187         p       = face->glyph_locations + gindex * 4;
00188         p_limit = face->glyph_locations + face->num_locations * 4;
00189 
00190         pos1 = FT_NEXT_ULONG( p );
00191         pos2 = pos1;
00192 
00193         if ( p + 4 <= p_limit )
00194           pos2 = FT_NEXT_ULONG( p );
00195       }
00196       else
00197       {
00198         p       = face->glyph_locations + gindex * 2;
00199         p_limit = face->glyph_locations + face->num_locations * 2;
00200 
00201         pos1 = FT_NEXT_USHORT( p );
00202         pos2 = pos1;
00203 
00204         if ( p + 2 <= p_limit )
00205           pos2 = FT_NEXT_USHORT( p );
00206 
00207         pos1 <<= 1;
00208         pos2 <<= 1;
00209       }
00210     }
00211 
00212     /* Check broken location data */
00213     if ( pos1 >= face->glyf_len )
00214     {
00215       FT_TRACE1(( "tt_face_get_location:"
00216                  " too large offset=0x%08lx found for gid=0x%04lx,"
00217                  " exceeding the end of glyf table (0x%08lx)\n",
00218                  pos1, gindex, face->glyf_len ));
00219       *asize = 0;
00220       return 0;
00221     }
00222 
00223     if ( pos2 >= face->glyf_len )
00224     {
00225       FT_TRACE1(( "tt_face_get_location:"
00226                  " too large offset=0x%08lx found for gid=0x%04lx,"
00227                  " truncate at the end of glyf table (0x%08lx)\n",
00228                  pos2, gindex + 1, face->glyf_len ));
00229       pos2 = face->glyf_len;
00230     }
00231 
00232     /* The `loca' table must be ordered; it refers to the length of */
00233     /* an entry as the difference between the current and the next  */
00234     /* position.  However, there do exist (malformed) fonts which   */
00235     /* don't obey this rule, so we are only able to provide an      */
00236     /* upper bound for the size.                                    */
00237     /*                                                              */
00238     /* We get (intentionally) a wrong, non-zero result in case the  */
00239     /* `glyf' table is missing.                                     */
00240     if ( pos2 >= pos1 )
00241       *asize = (FT_UInt)( pos2 - pos1 );
00242     else
00243       *asize = (FT_UInt)( face->glyf_len - pos1 );
00244 
00245     return pos1;
00246   }
00247 
00248 
00249   FT_LOCAL_DEF( void )
00250   tt_face_done_loca( TT_Face  face )
00251   {
00252     FT_Stream  stream = face->root.stream;
00253 
00254 
00255     FT_FRAME_RELEASE( face->glyph_locations );
00256     face->num_locations = 0;
00257   }
00258 
00259 
00260 
00261   /*************************************************************************/
00262   /*                                                                       */
00263   /* <Function>                                                            */
00264   /*    tt_face_load_cvt                                                   */
00265   /*                                                                       */
00266   /* <Description>                                                         */
00267   /*    Load the control value table into a face object.                   */
00268   /*                                                                       */
00269   /* <InOut>                                                               */
00270   /*    face   :: A handle to the target face object.                      */
00271   /*                                                                       */
00272   /* <Input>                                                               */
00273   /*    stream :: A handle to the input stream.                            */
00274   /*                                                                       */
00275   /* <Return>                                                              */
00276   /*    FreeType error code.  0 means success.                             */
00277   /*                                                                       */
00278   FT_LOCAL_DEF( FT_Error )
00279   tt_face_load_cvt( TT_Face    face,
00280                     FT_Stream  stream )
00281   {
00282 #ifdef TT_USE_BYTECODE_INTERPRETER
00283 
00284     FT_Error   error;
00285     FT_Memory  memory = stream->memory;
00286     FT_ULong   table_len;
00287 
00288 
00289     FT_TRACE2(( "CVT " ));
00290 
00291     error = face->goto_table( face, TTAG_cvt, stream, &table_len );
00292     if ( error )
00293     {
00294       FT_TRACE2(( "is missing\n" ));
00295 
00296       face->cvt_size = 0;
00297       face->cvt      = NULL;
00298       error          = TT_Err_Ok;
00299 
00300       goto Exit;
00301     }
00302 
00303     face->cvt_size = table_len / 2;
00304 
00305     if ( FT_NEW_ARRAY( face->cvt, face->cvt_size ) )
00306       goto Exit;
00307 
00308     if ( FT_FRAME_ENTER( face->cvt_size * 2L ) )
00309       goto Exit;
00310 
00311     {
00312       FT_Short*  cur   = face->cvt;
00313       FT_Short*  limit = cur + face->cvt_size;
00314 
00315 
00316       for ( ; cur < limit; cur++ )
00317         *cur = FT_GET_SHORT();
00318     }
00319 
00320     FT_FRAME_EXIT();
00321     FT_TRACE2(( "loaded\n" ));
00322 
00323 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
00324     if ( face->doblend )
00325       error = tt_face_vary_cvt( face, stream );
00326 #endif
00327 
00328   Exit:
00329     return error;
00330 
00331 #else /* !TT_USE_BYTECODE_INTERPRETER */
00332 
00333     FT_UNUSED( face   );
00334     FT_UNUSED( stream );
00335 
00336     return TT_Err_Ok;
00337 
00338 #endif
00339   }
00340 
00341 
00342   /*************************************************************************/
00343   /*                                                                       */
00344   /* <Function>                                                            */
00345   /*    tt_face_load_fpgm                                                  */
00346   /*                                                                       */
00347   /* <Description>                                                         */
00348   /*    Load the font program.                                             */
00349   /*                                                                       */
00350   /* <InOut>                                                               */
00351   /*    face   :: A handle to the target face object.                      */
00352   /*                                                                       */
00353   /* <Input>                                                               */
00354   /*    stream :: A handle to the input stream.                            */
00355   /*                                                                       */
00356   /* <Return>                                                              */
00357   /*    FreeType error code.  0 means success.                             */
00358   /*                                                                       */
00359   FT_LOCAL_DEF( FT_Error )
00360   tt_face_load_fpgm( TT_Face    face,
00361                      FT_Stream  stream )
00362   {
00363 #ifdef TT_USE_BYTECODE_INTERPRETER
00364 
00365     FT_Error  error;
00366     FT_ULong  table_len;
00367 
00368 
00369     FT_TRACE2(( "Font program " ));
00370 
00371     /* The font program is optional */
00372     error = face->goto_table( face, TTAG_fpgm, stream, &table_len );
00373     if ( error )
00374     {
00375       face->font_program      = NULL;
00376       face->font_program_size = 0;
00377       error                   = TT_Err_Ok;
00378 
00379       FT_TRACE2(( "is missing\n" ));
00380     }
00381     else
00382     {
00383       face->font_program_size = table_len;
00384       if ( FT_FRAME_EXTRACT( table_len, face->font_program ) )
00385         goto Exit;
00386 
00387       FT_TRACE2(( "loaded, %12d bytes\n", face->font_program_size ));
00388     }
00389 
00390   Exit:
00391     return error;
00392 
00393 #else /* !TT_USE_BYTECODE_INTERPRETER */
00394 
00395     FT_UNUSED( face   );
00396     FT_UNUSED( stream );
00397 
00398     return TT_Err_Ok;
00399 
00400 #endif
00401   }
00402 
00403 
00404   /*************************************************************************/
00405   /*                                                                       */
00406   /* <Function>                                                            */
00407   /*    tt_face_load_prep                                                  */
00408   /*                                                                       */
00409   /* <Description>                                                         */
00410   /*    Load the cvt program.                                              */
00411   /*                                                                       */
00412   /* <InOut>                                                               */
00413   /*    face   :: A handle to the target face object.                      */
00414   /*                                                                       */
00415   /* <Input>                                                               */
00416   /*    stream :: A handle to the input stream.                            */
00417   /*                                                                       */
00418   /* <Return>                                                              */
00419   /*    FreeType error code.  0 means success.                             */
00420   /*                                                                       */
00421   FT_LOCAL_DEF( FT_Error )
00422   tt_face_load_prep( TT_Face    face,
00423                      FT_Stream  stream )
00424   {
00425 #ifdef TT_USE_BYTECODE_INTERPRETER
00426 
00427     FT_Error  error;
00428     FT_ULong  table_len;
00429 
00430 
00431     FT_TRACE2(( "Prep program " ));
00432 
00433     error = face->goto_table( face, TTAG_prep, stream, &table_len );
00434     if ( error )
00435     {
00436       face->cvt_program      = NULL;
00437       face->cvt_program_size = 0;
00438       error                  = TT_Err_Ok;
00439 
00440       FT_TRACE2(( "is missing\n" ));
00441     }
00442     else
00443     {
00444       face->cvt_program_size = table_len;
00445       if ( FT_FRAME_EXTRACT( table_len, face->cvt_program ) )
00446         goto Exit;
00447 
00448       FT_TRACE2(( "loaded, %12d bytes\n", face->cvt_program_size ));
00449     }
00450 
00451   Exit:
00452     return error;
00453 
00454 #else /* !TT_USE_BYTECODE_INTERPRETER */
00455 
00456     FT_UNUSED( face   );
00457     FT_UNUSED( stream );
00458 
00459     return TT_Err_Ok;
00460 
00461 #endif
00462   }
00463 
00464 
00465   /*************************************************************************/
00466   /*                                                                       */
00467   /* <Function>                                                            */
00468   /*    tt_face_load_hdmx                                                  */
00469   /*                                                                       */
00470   /* <Description>                                                         */
00471   /*    Load the `hdmx' table into the face object.                        */
00472   /*                                                                       */
00473   /* <Input>                                                               */
00474   /*    face   :: A handle to the target face object.                      */
00475   /*                                                                       */
00476   /*    stream :: A handle to the input stream.                            */
00477   /*                                                                       */
00478   /* <Return>                                                              */
00479   /*    FreeType error code.  0 means success.                             */
00480   /*                                                                       */
00481 
00482   FT_LOCAL_DEF( FT_Error )
00483   tt_face_load_hdmx( TT_Face    face,
00484                      FT_Stream  stream )
00485   {
00486     FT_Error   error;
00487     FT_Memory  memory = stream->memory;
00488     FT_UInt    version, nn, num_records;
00489     FT_ULong   table_size, record_size;
00490     FT_Byte*   p;
00491     FT_Byte*   limit;
00492 
00493 
00494     /* this table is optional */
00495     error = face->goto_table( face, TTAG_hdmx, stream, &table_size );
00496     if ( error || table_size < 8 )
00497       return TT_Err_Ok;
00498 
00499     if ( FT_FRAME_EXTRACT( table_size, face->hdmx_table ) )
00500       goto Exit;
00501 
00502     p     = face->hdmx_table;
00503     limit = p + table_size;
00504 
00505     version     = FT_NEXT_USHORT( p );
00506     num_records = FT_NEXT_USHORT( p );
00507     record_size = FT_NEXT_ULONG( p );
00508 
00509     /* The maximum number of bytes in an hdmx device record is the */
00510     /* maximum number of glyphs + 2; this is 0xFFFF + 2; this is   */
00511     /* the reason why `record_size' is a long (which we read as    */
00512     /* unsigned long for convenience).  In practice, two bytes     */
00513     /* sufficient to hold the size value.                          */
00514     /*                                                             */
00515     /* There are at least two fonts, HANNOM-A and HANNOM-B version */
00516     /* 2.0 (2005), which get this wrong: The upper two bytes of    */
00517     /* the size value are set to 0xFF instead of 0x00.  We catch   */
00518     /* and fix this.                                               */
00519 
00520     if ( record_size >= 0xFFFF0000UL )
00521       record_size &= 0xFFFFU;
00522 
00523     /* The limit for `num_records' is a heuristic value. */
00524 
00525     if ( version != 0 || num_records > 255 || record_size > 0x10001L )
00526     {
00527       error = TT_Err_Invalid_File_Format;
00528       goto Fail;
00529     }
00530 
00531     if ( FT_NEW_ARRAY( face->hdmx_record_sizes, num_records ) )
00532       goto Fail;
00533 
00534     for ( nn = 0; nn < num_records; nn++ )
00535     {
00536       if ( p + record_size > limit )
00537         break;
00538 
00539       face->hdmx_record_sizes[nn] = p[0];
00540       p                          += record_size;
00541     }
00542 
00543     face->hdmx_record_count = nn;
00544     face->hdmx_table_size   = table_size;
00545     face->hdmx_record_size  = record_size;
00546 
00547   Exit:
00548     return error;
00549 
00550   Fail:
00551     FT_FRAME_RELEASE( face->hdmx_table );
00552     face->hdmx_table_size = 0;
00553     goto Exit;
00554   }
00555 
00556 
00557   FT_LOCAL_DEF( void )
00558   tt_face_free_hdmx( TT_Face  face )
00559   {
00560     FT_Stream  stream = face->root.stream;
00561     FT_Memory  memory = stream->memory;
00562 
00563 
00564     FT_FREE( face->hdmx_record_sizes );
00565     FT_FRAME_RELEASE( face->hdmx_table );
00566   }
00567 
00568 
00569   /*************************************************************************/
00570   /*                                                                       */
00571   /* Return the advance width table for a given pixel size if it is found  */
00572   /* in the font's `hdmx' table (if any).                                  */
00573   /*                                                                       */
00574   FT_LOCAL_DEF( FT_Byte* )
00575   tt_face_get_device_metrics( TT_Face  face,
00576                               FT_UInt  ppem,
00577                               FT_UInt  gindex )
00578   {
00579     FT_UInt   nn;
00580     FT_Byte*  result      = NULL;
00581     FT_ULong  record_size = face->hdmx_record_size;
00582     FT_Byte*  record      = face->hdmx_table + 8;
00583 
00584 
00585     for ( nn = 0; nn < face->hdmx_record_count; nn++ )
00586       if ( face->hdmx_record_sizes[nn] == ppem )
00587       {
00588         gindex += 2;
00589         if ( gindex < record_size )
00590           result = record + nn * record_size + gindex;
00591         break;
00592       }
00593 
00594     return result;
00595   }
00596 
00597 
00598 /* END */

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