tizen 2.3.1 release
[framework/graphics/freetype.git] / src / winfonts / winfnt.c
index a551896..4705c53 100644 (file)
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType font driver for Windows FNT/FON files                       */
 /*                                                                         */
-/*  Copyright 1996-2004, 2006-2012 by                                      */
+/*  Copyright 1996-2004, 2006-2014 by                                      */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*  Copyright 2003 Huw D M Davies for Codeweavers                          */
 /*  Copyright 2007 Dmitry Timoshkov for Codeweavers                        */
 
     FT_FRAME_START( 248 ),
       FT_FRAME_ULONG_LE  ( magic ),   /* PE00 */
-      FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */
+      FT_FRAME_USHORT_LE ( machine ), /* 0x014C - i386 */
       FT_FRAME_USHORT_LE ( number_of_sections ),
       FT_FRAME_SKIP_BYTES( 12 ),
       FT_FRAME_USHORT_LE ( size_of_optional_header ),
       FT_FRAME_SKIP_BYTES( 2 ),
-      FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */
+      FT_FRAME_USHORT_LE ( magic32 ), /* 0x10B */
       FT_FRAME_SKIP_BYTES( 110 ),
       FT_FRAME_ULONG_LE  ( rsrc_virtual_address ),
       FT_FRAME_ULONG_LE  ( rsrc_size ),
          header->version != 0x300 )
     {
       FT_TRACE2(( "  not a Windows FNT file\n" ));
-      error = FNT_Err_Unknown_File_Format;
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
 
     if ( header->file_size < size )
     {
       FT_TRACE2(( "  not a Windows FNT file\n" ));
-      error = FNT_Err_Unknown_File_Format;
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
 
     if ( header->file_type & 1 )
     {
       FT_TRACE2(( "[can't handle vector FNT fonts]\n" ));
-      error = FNT_Err_Unknown_File_Format;
+      error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
 
          FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) )
       goto Exit;
 
-    error = FNT_Err_Unknown_File_Format;
+    error = FT_ERR( Unknown_File_Format );
     if ( mz_header.magic == WINFNT_MZ_MAGIC )
     {
       /* yes, now look for an NE header in the file */
            FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )
         goto Exit;
 
-      error = FNT_Err_Unknown_File_Format;
+      error = FT_ERR( Unknown_File_Format );
       if ( ne_header.magic == WINFNT_NE_MAGIC )
       {
         /* good, now look into the resource table for each FNT resource */
         if ( !font_count || !font_offset )
         {
           FT_TRACE2(( "this file doesn't contain any FNT resources\n" ));
-          error = FNT_Err_Invalid_File_Format;
+          error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
         if ( font_count * 118UL > stream->size )
         {
           FT_TRACE2(( "invalid number of faces\n" ));
-          error = FNT_Err_Invalid_File_Format;
+          error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
 
         if ( face_index >= font_count )
         {
-          error = FNT_Err_Invalid_Argument;
+          error = FT_THROW( Invalid_Argument );
           goto Exit;
         }
         else if ( face_index < 0 )
                     pe32_header.rsrc_size ));
 
         if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ ||
-             pe32_header.machine != 0x014c /* i386 */                        ||
-             pe32_header.size_of_optional_header != 0xe0 /* FIXME */         ||
-             pe32_header.magic32 != 0x10b                                    )
+             pe32_header.machine != 0x014C /* i386 */                        ||
+             pe32_header.size_of_optional_header != 0xE0 /* FIXME */         ||
+             pe32_header.magic32 != 0x10B                                    )
         {
           FT_TRACE2(( "this file has an invalid PE header\n" ));
-          error = FNT_Err_Invalid_File_Format;
+          error = FT_THROW( Invalid_File_Format );
           goto Exit;
         }
 
         }
 
         FT_TRACE2(( "this file doesn't contain any resources\n" ));
-        error = FNT_Err_Invalid_File_Format;
+        error = FT_THROW( Invalid_File_Format );
         goto Exit;
 
       Found_rsrc_section:
 
           if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
           {
-            error = FNT_Err_Invalid_File_Format;
+            error = FT_THROW( Invalid_File_Format );
             goto Exit;
           }
 
 
             if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
             {
-              error = FNT_Err_Invalid_File_Format;
+              error = FT_THROW( Invalid_File_Format );
               goto Exit;
             }
 
 
               if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ )
               {
-                error = FNT_Err_Invalid_File_Format;
+                error = FT_THROW( Invalid_File_Format );
                 goto Exit;
               }
 
       if ( !face->root.num_faces )
       {
         FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" ));
-        error = FNT_Err_Invalid_File_Format;
+        error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
 
       if ( face_index >= face->root.num_faces )
       {
-        error = FNT_Err_Invalid_Argument;
+        error = FT_THROW( Invalid_Argument );
         goto Exit;
       }
     }
 
 
   static FT_Error
-  fnt_cmap_init( FNT_CMap  cmap )
+  fnt_cmap_init( FNT_CMap    cmap,
+                 FT_Pointer  pointer )
   {
     FNT_Face  face = (FNT_Face)FT_CMAP_FACE( cmap );
     FNT_Font  font = face->font;
 
+    FT_UNUSED( pointer );
+
 
     cmap->first = (FT_UInt32)  font->header.first_char;
     cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 );
     if ( !error && face_index < 0 )
       goto Exit;
 
-    if ( error == FNT_Err_Unknown_File_Format )
+    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
     {
       /* this didn't work; try to load a single FNT font */
       FNT_Font  font;
       if ( !error )
       {
         if ( face_index > 0 )
-          error = FNT_Err_Invalid_Argument;
+          error = FT_THROW( Invalid_Argument );
         else if ( face_index < 0 )
           goto Exit;
       }
 
       root->face_index = face_index;
 
-      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
-                         FT_FACE_FLAG_HORIZONTAL;
+      root->face_flags |= FT_FACE_FLAG_FIXED_SIZES |
+                          FT_FACE_FLAG_HORIZONTAL;
 
       if ( font->header.avg_width == font->header.max_width )
         root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
       if ( font->header.last_char < font->header.first_char )
       {
         FT_TRACE2(( "invalid number of glyphs\n" ));
-        error = FNT_Err_Invalid_File_Format;
+        error = FT_THROW( Invalid_File_Format );
         goto Fail;
       }
 
       if ( font->header.face_name_offset >= font->header.file_size )
       {
         FT_TRACE2(( "invalid family name offset\n" ));
-        error = FNT_Err_Invalid_File_Format;
+        error = FT_THROW( Invalid_File_Format );
         goto Fail;
       }
       family_size = font->header.file_size - font->header.face_name_offset;
                                    header->ascent ) * 64;
     size->metrics.max_advance = header->max_width * 64;
 
-    return FNT_Err_Ok;
+    return FT_Err_Ok;
   }
 
 
     FNT_Face          face    = (FNT_Face)size->face;
     FT_WinFNT_Header  header  = &face->font->header;
     FT_Bitmap_Size*   bsize   = size->face->available_sizes;
-    FT_Error          error   = FNT_Err_Invalid_Pixel_Size;
+    FT_Error          error   = FT_ERR( Invalid_Pixel_Size );
     FT_Long           height;
 
 
     {
     case FT_SIZE_REQUEST_TYPE_NOMINAL:
       if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
-        error = FNT_Err_Ok;
+        error = FT_Err_Ok;
       break;
 
     case FT_SIZE_REQUEST_TYPE_REAL_DIM:
       if ( height == header->pixel_height )
-        error = FNT_Err_Ok;
+        error = FT_Err_Ok;
       break;
 
     default:
-      error = FNT_Err_Unimplemented_Feature;
+      error = FT_THROW( Unimplemented_Feature );
       break;
     }
 
   {
     FNT_Face    face   = (FNT_Face)FT_SIZE_FACE( size );
     FNT_Font    font;
-    FT_Error    error  = FNT_Err_Ok;
+    FT_Error    error  = FT_Err_Ok;
     FT_Byte*    p;
     FT_Int      len;
     FT_Bitmap*  bitmap = &slot->bitmap;
 
     if ( !face )
     {
-      error = FNT_Err_Invalid_Argument;
+      error = FT_THROW( Invalid_Face_Handle );
       goto Exit;
     }
 
     font = face->font;
 
-    if ( !font ||
+    if ( !font                                                   ||
          glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) )
     {
-      error = FNT_Err_Invalid_Argument;
+      error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
 
+    FT_TRACE1(( "FNT_Load_Glyph: glyph index %d\n", glyph_index ));
+
     if ( glyph_index > 0 )
       glyph_index--;                           /* revert to real index */
     else
-      glyph_index = font->header.default_char; /* the .notdef glyph */
+      glyph_index = font->header.default_char; /* the `.notdef' glyph  */
 
     new_format = FT_BOOL( font->header.version == 0x300 );
     len        = new_format ? 6 : 4;
 
-    /* jump to glyph entry */
-    p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index;
+    /* get glyph width and offset */
+    offset = ( new_format ? 148 : 118 ) + len * glyph_index;
+
+    if ( offset >= font->header.file_size - 2 - ( new_format ? 4 : 2 ) )
+    {
+      FT_TRACE2(( "invalid FNT offset\n" ));
+      error = FT_THROW( Invalid_File_Format );
+      goto Exit;
+    }
+
+    p = font->fnt_frame + offset;
 
     bitmap->width = FT_NEXT_SHORT_LE( p );
 
+    /* jump to glyph entry */
     if ( new_format )
       offset = FT_NEXT_ULONG_LE( p );
     else
     if ( offset >= font->header.file_size )
     {
       FT_TRACE2(( "invalid FNT offset\n" ));
-      error = FNT_Err_Invalid_File_Format;
+      error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
       bitmap->rows       = font->header.pixel_height;
       bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
 
-      if ( offset + pitch * bitmap->rows >= font->header.file_size )
+      if ( offset + pitch * bitmap->rows > font->header.file_size )
       {
         FT_TRACE2(( "invalid bitmap width\n" ));
-        error = FNT_Err_Invalid_File_Format;
+        error = FT_THROW( Invalid_File_Format );
         goto Exit;
       }
 
     0,                    /* FT_Slot_InitFunc */
     0,                    /* FT_Slot_DoneFunc */
 
-#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
-    ft_stub_set_char_sizes,
-    ft_stub_set_pixel_sizes,
-#endif
     FNT_Load_Glyph,
 
     0,                    /* FT_Face_GetKerningFunc  */