Upload tizen 2.0 beta source
[framework/graphics/freetype.git] / src / sfnt / sfobjs.c
index 6e35e2d..d7be631 100644 (file)
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    SFNT object management (base).                                       */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 by */
+/*  Copyright 1996-2008, 2010-2011 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 
       FT_FRAME_START( 8 ),
         FT_FRAME_LONG( version ),
-        FT_FRAME_LONG( count   ),
+        FT_FRAME_LONG( count   ),  /* this is ULong in the specs */
       FT_FRAME_END
     };
 
          tag != TTAG_true    &&
          tag != TTAG_typ1    &&
          tag != 0x00020000UL )
+    {
+      FT_TRACE2(( "  not a font using the SFNT container format\n" ));
       return SFNT_Err_Unknown_File_Format;
+    }
 
     face->ttc_header.tag = TTAG_ttcf;
 
       if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
         return error;
 
+      if ( face->ttc_header.count == 0 )
+        return SFNT_Err_Invalid_Table;
+
+      /* a rough size estimate: let's conservatively assume that there   */
+      /* is just a single table info in each subfont header (12 + 16*1 = */
+      /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
+      /* size of the TTC header plus `28*count' bytes for all subfont    */
+      /* headers                                                         */
+      if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
+        return SFNT_Err_Array_Too_Large;
+
       /* now read the offsets of each font in the file */
       if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
         return error;
     {
       sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
       if ( !sfnt )
-        return SFNT_Err_Invalid_File_Format;
+      {
+        FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
+        return SFNT_Err_Missing_Module;
+      }
 
       face->sfnt       = sfnt;
       face->goto_table = sfnt->goto_table;
 
     FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
 
+    FT_TRACE2(( "SFNT driver\n" ));
+
     error = sfnt_open_font( stream, face );
     if ( error )
       return error;
     FT_UNUSED( face_index );
 
     /* Check parameters */
-    
+
     {
       FT_Int  i;
 
 
     /* do we have outlines in there? */
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-    has_outline   = FT_BOOL( face->root.internal->incremental_interface != 0 ||
-                             tt_face_lookup_table( face, TTAG_glyf )    != 0 ||
-                             tt_face_lookup_table( face, TTAG_CFF )     != 0 );
+    has_outline = FT_BOOL( face->root.internal->incremental_interface != 0 ||
+                           tt_face_lookup_table( face, TTAG_glyf )    != 0 ||
+                           tt_face_lookup_table( face, TTAG_CFF )     != 0 );
 #else
-    has_outline   = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
-                             tt_face_lookup_table( face, TTAG_CFF )  != 0 );
+    has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) != 0 ||
+                           tt_face_lookup_table( face, TTAG_CFF )  != 0 );
 #endif
 
     is_apple_sbit = 0;
         if ( face->format_tag == TTAG_true )
         {
           FT_TRACE2(( "This is an SFNT Mac font.\n" ));
+
           has_outline = 0;
-          error = SFNT_Err_Ok;
+          error       = SFNT_Err_Ok;
         }
         else
         {
       LOAD_( os2 );
       if ( error )
       {
-        if ( error != SFNT_Err_Table_Missing )
-          goto Exit;
-
+        /* we treat the table as missing if there are any errors */
         face->os2.version = 0xFFFFU;
       }
     }
         /*      table cannot be used to compute the text height reliably! */
         /*                                                                */
 
-        /* The ascender/descender/height are computed from the OS/2 table */
-        /* when found.  Otherwise, they're taken from the horizontal      */
-        /* header.                                                        */
-        /*                                                                */
+        /* The ascender and descender are taken from the `hhea' table. */
+        /* If zero, they are taken from the `OS/2' table.              */
 
         root->ascender  = face->horizontal.Ascender;
         root->descender = face->horizontal.Descender;
 
-        root->height    = (FT_Short)( root->ascender - root->descender +
-                                      face->horizontal.Line_Gap );
-
-#if 0
-        /* if the line_gap is 0, we add an extra 15% to the text height --  */
-        /* this computation is based on various versions of Times New Roman */
-        if ( face->horizontal.Line_Gap == 0 )
-          root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 );
-#endif /* 0 */
+        root->height = (FT_Short)( root->ascender - root->descender +
+                                   face->horizontal.Line_Gap );
 
-#if 0
-        /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */
-        /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF             */
-        if ( face->os2.version != 0xFFFFU && root->ascender )
+        if ( !( root->ascender || root->descender ) )
         {
-          FT_Int  height;
-
+          if ( face->os2.version != 0xFFFFU )
+          {
+            if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
+            {
+              root->ascender  = face->os2.sTypoAscender;
+              root->descender = face->os2.sTypoDescender;
 
-          root->ascender  =  face->os2.sTypoAscender;
-          root->descender = -face->os2.sTypoDescender;
+              root->height = (FT_Short)( root->ascender - root->descender +
+                                         face->os2.sTypoLineGap );
+            }
+            else
+            {
+              root->ascender  =  (FT_Short)face->os2.usWinAscent;
+              root->descender = -(FT_Short)face->os2.usWinDescent;
 
-          height = root->ascender + root->descender + face->os2.sTypoLineGap;
-          if ( height > root->height )
-            root->height = height;
+              root->height = (FT_UShort)( root->ascender - root->descender );
+            }
+          }
         }
-#endif /* 0 */
 
         root->max_advance_width  = face->horizontal.advance_Width_Max;
         root->max_advance_height = (FT_Short)( face->vertical_info