shithub: freetype+ttf2subf

Download patch

ref: ab9cc277c2d695b2d253610d9867256aa2a3ad8f
parent: 43a2f656a71aea4d735dcdff201fed120479f707
author: David Turner <[email protected]>
date: Fri Jul 7 15:46:01 EDT 2000

added Windows FNT/FON font driver

git/fs: mount .git/fs: mount/attach disallowed
--- /dev/null
+++ b/src/winfonts/module.mk
@@ -1,0 +1,6 @@
+make_module_list: add_windows_driver
+
+add_windows_driver:
+	$(OPEN_DRIVER)winfnt_driver_class$(CLOSE_DRIVER)
+	$(ECHO_DRIVER)winfnt    $(ECHO_DRIVER_DESC)Windows bitmap fonts with extension *.fnt or *.fon$(ECHO_DRIVER_DONE)
+
--- /dev/null
+++ b/src/winfonts/rules.mk
@@ -1,0 +1,71 @@
+#
+# FreeType 2 Windows FNT/FON driver configuration rules
+#
+
+
+# Copyright 1996-2000 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+# Windows driver directory
+#
+FNT_DIR  := $(SRC_)winfonts
+FNT_DIR_ := $(FNT_DIR)$(SEP)
+
+
+# additional include flags used when compiling the driver
+#
+FNT_INCLUDE := $(FNT_DIR)
+
+# compilation flags for the driver
+#
+FNT_CFLAGS  := $(FNT_INCLUDE:%=$I%)
+FNT_COMPILE := $(FT_COMPILE) $(FNT_CFLAGS)
+
+
+# Windows driver sources (i.e., C files)
+#
+FNT_DRV_SRC := $(FNT_DIR_)winfnt.c
+
+# Windows driver headers
+#
+FNT_DRV_H := $(FNT_DRV_SRC:%.c=%.h)
+
+
+# Windows driver object(s)
+#
+#   FNT_DRV_OBJ_M is used during `multi' builds
+#   FNT_DRV_OBJ_S is used during `single' builds
+#
+FNT_DRV_OBJ_M := $(FNT_DRV_SRC:$(FNT_DIR_)%.c=$(OBJ_)%.$O)
+FNT_DRV_OBJ_S := $(OBJ_)winfnt.$O
+
+# Windows driver source file for single build
+#
+FNT_DRV_SRC_S := $(FNT_DIR_)winfnt.c
+
+
+# Windows driver - single object
+#
+$(FNT_DRV_OBJ_S): $(FNT_DRV_SRC_S) $(FNT_DRV_SRC) $(FREETYPE_H) $(FNT_DRV_H)
+	$(FNT_COMPILE) $T$@ $(FNT_DRV_SRC_S)
+
+
+# Windows driver - multiple objects
+#
+$(OBJ_)%.$O: $(FNT_DIR_)%.c $(FREETYPE_H) $(FNT_DRV_H)
+	$(FNT_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(FNT_DRV_OBJ_S)
+DRV_OBJS_M += $(FNT_DRV_OBJ_M)
+
+# EOF
--- /dev/null
+++ b/src/winfonts/winfnt.c
@@ -1,0 +1,566 @@
+/***************************************************************************/
+/*                                                                         */
+/*  winfnt.c                                                               */
+/*                                                                         */
+/*    FreeType font driver for Windows FNT/FON files                       */
+/*                                                                         */
+/*  Copyright 1996-2000 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used        */
+/*  modified and distributed under the terms of the FreeType project       */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#include <winfnt.h>
+#include <freetype/fterrors.h>
+#include <freetype/internal/ftstream.h>
+#include <freetype/internal/ftdebug.h>
+#include <freetype/internal/ftobjs.h>
+
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_ttobjs
+
+  static const FT_Frame_Field  winmz_header_fields[] =
+          { FT_FRAME_START( 64 ),
+              FT_FRAME_USHORT_LE ( WinMZ_Header, magic ),
+              FT_FRAME_SKIP_BYTES( 29*2 ),
+              FT_FRAME_ULONG_LE  ( WinMZ_Header, lfanew ),
+            FT_FRAME_END };
+
+  static const FT_Frame_Field  winne_header_fields[] =
+          { FT_FRAME_START( 40 ),
+              FT_FRAME_USHORT_LE( WinNE_Header, magic ),
+              FT_FRAME_SKIP_BYTES( 34 ),
+              FT_FRAME_USHORT_LE( WinNE_Header, resource_tab_offset ),
+              FT_FRAME_USHORT_LE( WinNE_Header, rname_tab_offset ),
+            FT_FRAME_END };
+
+
+  static const FT_Frame_Field  winfnt_header_fields[] =
+          { FT_FRAME_START( 134 ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, version ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, file_size ),
+               FT_FRAME_BYTES    ( WinFNT_Header, copyright, 60 ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, file_type ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, nominal_point_size ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, vertical_resolution ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, horizontal_resolution ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, ascent ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, internal_leading ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, external_leading ),
+               FT_FRAME_BYTE     ( WinFNT_Header, italic ),
+               FT_FRAME_BYTE     ( WinFNT_Header, underline ),
+               FT_FRAME_BYTE     ( WinFNT_Header, strike_out ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, weight ),
+               FT_FRAME_BYTE     ( WinFNT_Header, charset ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, pixel_width ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, pixel_height ),
+               FT_FRAME_BYTE     ( WinFNT_Header, pitch_and_family ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, avg_width ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, max_width ),
+               FT_FRAME_BYTE     ( WinFNT_Header, first_char ),
+               FT_FRAME_BYTE     ( WinFNT_Header, last_char ),
+               FT_FRAME_BYTE     ( WinFNT_Header, default_char ),
+               FT_FRAME_BYTE     ( WinFNT_Header, break_char ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, bytes_per_row ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, device_offset ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, face_name_offset ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, bits_pointer ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, bits_offset ),
+               FT_FRAME_BYTE     ( WinFNT_Header, reserved ),
+               FT_FRAME_ULONG_LE ( WinFNT_Header, flags ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, A_space ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, B_space ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, C_space ),
+               FT_FRAME_USHORT_LE( WinFNT_Header, color_table_offset ),
+               FT_FRAME_BYTES    ( WinFNT_Header, reserved, 4 ),
+               
+            FT_FRAME_END };
+
+
+  static
+  void      fnt_done_font( FT_Stream  stream,
+                           FNT_Font*  font )
+  {
+    if (font->fnt_frame)
+      RELEASE_Frame( font->fnt_frame );
+      
+    font->fnt_size  = 0;
+    font->fnt_frame = 0;
+  }                           
+
+
+  static
+  FT_Error  fnt_load_font( FT_Stream    stream,
+                           FNT_Font*    font )
+  {
+    FT_Error        error;
+    WinFNT_Header*  header   = &font->header;
+    
+    /* first of all, read the FNT header */
+    if ( FILE_Seek  ( font->offset )                 ||
+         READ_Fields( winfnt_header_fields, header ) )
+      goto Exit;
+
+    /* check header */
+    if ( header->version != 0x200 &&
+         header->version != 0x300 )
+    {
+      FT_TRACE2(( "not a valid FNT file\n" ));
+      error = FT_Err_Unknown_File_Format;
+      goto Exit;
+    }
+
+    if ( header->file_type & 1 )
+    {
+      FT_TRACE2(( "can't handle vector FNT fonts\n" ));
+      error = FT_Err_Unknown_File_Format;
+      goto Exit;
+    }
+
+    /* small fixup. some fonts have the "pixel_width" field set to 0 */
+    if ( header->pixel_width == 0 )
+      header->pixel_width = header->pixel_height;
+
+    /* this is a FNT file/table, we now extract its frame */
+    if ( FILE_Seek( font->offset )                        ||
+         EXTRACT_Frame( header->file_size, font->fnt_frame ) )
+      goto Exit;
+
+  Exit:
+    return error;
+  }                           
+
+
+
+  static
+  void      fnt_done_fonts( FNT_Face    face )
+  {
+    FT_Memory  memory = FT_FACE(face)->memory;
+    FT_Stream  stream = FT_FACE(face)->stream;
+    FNT_Font*  cur    = face->fonts;
+    FNT_Font*  limit  = cur + face->num_fonts;
+    
+    for ( ; cur < limit; cur++ )
+      fnt_done_font( stream, cur );
+      
+    FREE( face->fonts );
+    face->num_fonts = 0;
+  }
+
+
+
+  static
+  FT_Error  fnt_get_dll_fonts( FNT_Face   face )
+  {
+    FT_Error      error;
+    FT_Stream     stream = FT_FACE(face)->stream;
+    FT_Memory     memory = FT_FACE(face)->memory;
+    WinMZ_Header  mz_header;
+
+    face->fonts     = 0;
+    face->num_fonts = 0;
+
+    /* does it begin with a MZ header ?? */    
+    if ( FILE_Seek( 0 )                                 ||
+         READ_Fields( winmz_header_fields, &mz_header ) )
+      goto Exit;
+
+    if ( mz_header.magic == WINFNT_MZ_MAGIC )
+    {
+      /* yes, now look for a NE header in the file */
+      WinNE_Header  ne_header;
+      
+      if ( FILE_Seek( mz_header.lfanew )                  ||
+           READ_Fields( winne_header_fields, &ne_header ) )
+        goto Exit;
+      
+      if ( ne_header.magic == WINFNT_NE_MAGIC )
+      {
+        /* good, now look in the resource table for each FNT resource */
+        FT_ULong  res_offset = mz_header.lfanew + ne_header.resource_tab_offset;
+        
+        FT_UShort        size_shift;
+        FT_UShort        font_count  = 0;
+        FT_ULong         font_offset = 0;
+        
+        if ( FILE_Seek( res_offset ) ||
+             ACCESS_Frame( ne_header.rname_tab_offset -
+                           ne_header.resource_tab_offset ) )
+          goto Exit;
+        
+        size_shift = GET_UShortLE();
+        
+        for (;;)
+        {
+          FT_UShort  type_id, count;
+          
+          type_id = GET_UShortLE();
+          if (!type_id)
+            break;
+            
+          count = GET_UShortLE();
+          
+          if (type_id == 0x8008)
+          {
+            font_count  = count;
+            font_offset = FILE_Pos() + 4 + (stream->cursor - stream->limit);
+            break;
+          }
+          
+          stream->cursor += 4 + count*12;
+        }
+        FORGET_Frame();
+
+        if ( !font_count || !font_offset )
+        {
+          FT_TRACE2(( "This file doesn't contain any FNT resource !!\n" ));
+          error = FT_Err_Unknown_File_Format;
+          goto Exit;
+        }    
+
+        if ( FILE_Seek( font_offset )                         ||
+             ALLOC_ARRAY( face->fonts, font_count, FNT_Font ) )        
+          goto Exit;
+        
+        face->num_fonts = font_count;
+        
+        if ( ACCESS_Frame( (FT_Long)font_count * 12 ) )
+          goto Exit;
+          
+        /* now read the offset and position of each FNT font */
+        {
+          FNT_Font*  cur   = face->fonts;
+          FNT_Font*  limit = cur + font_count;
+          
+          for ( ; cur < limit; cur++ )
+          {
+            cur->offset     = (FT_ULong)GET_UShortLE() << size_shift;
+            cur->fnt_size   = (FT_ULong)GET_UShortLE() << size_shift;
+            cur->size_shift = size_shift;
+            stream->cursor += 8;
+          }
+        }
+        FORGET_Frame();
+        
+        /* finally, try to load each font there */
+        {
+          FNT_Font*  cur   = face->fonts;
+          FNT_Font*  limit = cur + font_count;
+          
+          for ( ; cur < limit; cur++ )
+          {
+            error = fnt_load_font( stream, cur );
+            if (error) goto Fail;
+          }
+        }
+      }
+    }
+
+  Fail:
+    if (error)
+      fnt_done_fonts( face );
+
+  Exit:
+    return error;
+  }
+
+
+
+  static
+  void  FNT_Done_Face( FNT_Face  face )
+  {
+    FT_Memory  memory = FT_FACE_MEMORY(face);
+    
+    fnt_done_fonts(face);
+    
+    FREE( face->root.available_sizes );
+    face->root.num_fixed_sizes = 0;
+  }
+
+  
+  
+  static
+  FT_Error  FNT_Init_Face( FT_Stream      stream,
+                           FNT_Face       face,
+                           FT_Int         face_index,
+                           FT_Int         num_params,
+                           FT_Parameter*  params )
+  {
+    FT_Error   error;
+    FT_Memory  memory = FT_FACE_MEMORY(face);
+    
+    FT_UNUSED(num_params);
+    FT_UNUSED(params);
+    FT_UNUSED(face_index);
+    
+    /* try to load several fonts from a DLL */
+    error = fnt_get_dll_fonts( face );
+    if (error)
+    {
+      /* this didn't work, now try to load a single FNT font */
+      FT_Memory  memory = FT_FACE_MEMORY(face);
+      FNT_Font*  font;
+      
+      if ( ALLOC( face->fonts, sizeof(*face->fonts) ) )
+        goto Exit;
+        
+      face->num_fonts = 1;
+      font            = face->fonts;
+      
+      font->offset   = 0;
+      font->fnt_size = stream->size;
+      
+      error = fnt_load_font( stream, font );
+      if (error)
+        goto Fail;
+    }
+
+    /* all right, one or more fonts were loaded, we now need to */
+    /* fill the root FT_Face fields with relevant information.. */ 
+    {
+      FT_Face   root  = FT_FACE(face);
+      FNT_Font* fonts = face->fonts;
+      FNT_Font* limit = fonts + face->num_fonts;
+      FNT_Font* cur;
+
+      root->num_faces  = 1;
+      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
+                         FT_FACE_FLAG_HORIZONTAL;
+
+      if ( fonts->header.avg_width == fonts->header.max_width )
+        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+      
+      if ( fonts->header.italic )
+        root->style_flags |= FT_STYLE_FLAG_ITALIC;
+        
+      if ( fonts->header.weight >= 800 )
+        root->style_flags |= FT_STYLE_FLAG_BOLD;
+
+      /* Setup the "fixed_sizes" array */
+      if ( ALLOC_ARRAY( root->available_sizes, face->num_fonts, FT_Bitmap_Size ) )
+        goto Fail;
+
+      root->num_fixed_sizes = face->num_fonts;  
+      
+      {
+        FT_Bitmap_Size*  size = root->available_sizes;
+        
+        for ( cur = fonts; cur < limit; cur++, size++ )
+        {
+          size->width  = cur->header.pixel_width;
+          size->height = cur->header.pixel_height;
+        }
+      }
+      
+      /* Setup the "charmaps" array */
+      root->charmaps     = &face->charmap_handle;
+      root->num_charmaps = 1;
+
+      face->charmap.encoding    = ft_encoding_unicode;
+      face->charmap.platform_id = 3;
+      face->charmap.encoding_id = 1;
+      face->charmap.face        = root;
+      
+      face->charmap_handle = &face->charmap;
+      
+      root->charmap = face->charmap_handle;
+
+      /* setup remaining flags */      
+      root->num_glyphs = fonts->header.last_char - fonts->header.first_char + 1;
+      
+      root->family_name = (FT_String*)fonts->fnt_frame + fonts->header.face_name_offset;
+      root->style_name  = "Regular";
+      if (root->style_flags & FT_STYLE_FLAG_BOLD)
+      {
+        if (root->style_flags & FT_STYLE_FLAG_ITALIC)
+          root->style_name = "Bold Italic";
+        else
+          root->style_name = "Bold";
+      }
+      else if (root->style_flags & FT_STYLE_FLAG_ITALIC)
+        root->style_name = "Italic";
+    }
+    
+    
+  Fail:
+    if (error)
+      FNT_Done_Face( face );
+    
+  Exit:
+    return error;
+  }                           
+
+
+
+  static
+  FT_Error  FNT_Set_Pixel_Size( FNT_Size  size )
+  {
+    /* look up a font corresponding to the current pixel size */
+    FNT_Face   face  = (FNT_Face)FT_SIZE_FACE(size);
+    FNT_Font*  cur   = face->fonts;
+    FNT_Font*  limit = cur + face->num_fonts;
+
+    size->font = 0;
+    for ( ; cur < limit; cur++ )
+    {
+      /* we only compare the character height, as fonts used some strange */
+      /* values..                                                         */
+      if ( cur->header.pixel_height == size->root.metrics.y_ppem )
+      {
+        size->font = cur;
+        break;
+      }           
+    }
+
+    return (size->font ? FT_Err_Ok : FT_Err_Invalid_Argument);    
+  }
+
+
+  static
+  FT_UInt  FNT_Get_Char_Index( FT_CharMap  charmap,
+                               FT_ULong    char_code )
+  {
+    FT_UInt  result = char_code;
+    
+    if (charmap)
+    {
+      FNT_Font*  font  = ((FNT_Face)charmap->face)->fonts;
+      FT_UInt    first = font->header.first_char;
+      FT_UInt    count = font->header.last_char - first + 1;
+      
+      char_code -= first;
+      if (char_code < count)
+        result = char_code;
+      else
+        result = font->header.default_char - first;
+    }
+    return result;
+  }
+
+
+
+  static
+  FT_Error  FNT_Load_Glyph( FT_GlyphSlot  slot,
+                            FNT_Size      size,
+                            FT_UInt       glyph_index,
+                            FT_Int        load_flags )
+  {
+    FNT_Font*  font  = size->font;
+    FT_Error   error = 0;
+    FT_Byte*   p;
+    FT_Int     len;
+    FT_Bitmap* bitmap = &slot->bitmap;
+    FT_ULong   offset;
+    FT_Bool    new_format;
+    
+    FT_UNUSED(slot);
+    FT_UNUSED(load_flags);
+    
+    if (!font)
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+
+    new_format = font->header.version == 0x300;
+    len        = new_format ? 6 : 4;
+
+  /* jump to glyph entry */    
+    p   = font->fnt_frame + 118 + len*glyph_index;
+      
+    bitmap->width = NEXT_ShortLE(p);
+    
+    if (new_format)
+      offset = NEXT_ULongLE(p);
+    else
+      offset = NEXT_UShortLE(p);
+    
+   /* jump to glyph data */
+    p = font->fnt_frame + /* font->header.bits_offset */ + offset;
+    
+   /* allocate and build bitmap */
+    {
+      FT_Memory memory = FT_FACE_MEMORY(slot->face);
+      FT_Int    pitch = (bitmap->width+7) >> 3;
+      FT_Byte*  column;
+      FT_Byte*  write;
+      
+      bitmap->pitch    = pitch;
+      bitmap->rows     = font->header.pixel_height;
+      bitmap->pixel_mode = ft_pixel_mode_mono;
+      
+      if ( ALLOC( bitmap->buffer, pitch * bitmap->rows ) )
+        goto Exit;
+      
+      
+      column = (FT_Byte*)bitmap->buffer;
+
+      for ( ; pitch > 0; pitch--, column++ )
+      {
+        FT_Byte*  limit = p + bitmap->rows;
+        
+        for ( write = column; p < limit; p++, write += bitmap->pitch )
+          write[0] = p[0];
+      }
+    }
+    
+    slot->flags        = ft_glyph_own_bitmap;
+    slot->bitmap_left  = 0;
+    slot->bitmap_top   = font->header.ascent;
+    slot->format       = ft_glyph_format_bitmap;
+    
+    /* now set up metrics */
+    slot->metrics.horiAdvance  = bitmap->width << 6;
+    slot->metrics.horiBearingX = 0;
+    slot->metrics.horiBearingY = slot->bitmap_top << 6;
+
+    slot->linearHoriAdvance    = (FT_Fixed)bitmap->width << 16;
+    
+  Exit:
+    return error;
+  }                            
+
+  const FT_Driver_Class   winfnt_driver_class =
+  {
+    {
+      ft_module_font_driver,
+      sizeof( FT_DriverRec ),
+      
+      "winfonts",
+      0x10000,
+      0x20000,
+      
+      0,
+      
+      (FT_Module_Constructor)  0,
+      (FT_Module_Destructor)   0,
+      (FT_Module_Requester)    0
+    },
+    
+    sizeof( FNT_FaceRec ),
+    sizeof( FNT_SizeRec ),
+    sizeof( FT_GlyphSlotRec ),
+    
+    (FTDriver_initFace)     FNT_Init_Face,
+    (FTDriver_doneFace)     FNT_Done_Face,
+    (FTDriver_initSize)     0,
+    (FTDriver_doneSize)     0,
+    (FTDriver_initGlyphSlot)0,
+    (FTDriver_doneGlyphSlot)0,
+
+    (FTDriver_setCharSizes) FNT_Set_Pixel_Size,
+    (FTDriver_setPixelSizes)FNT_Set_Pixel_Size,
+
+    (FTDriver_loadGlyph)    FNT_Load_Glyph,
+    (FTDriver_getCharIndex) FNT_Get_Char_Index,
+
+    (FTDriver_getKerning)   0,
+    (FTDriver_attachFile)   0,
+    (FTDriver_getAdvances)  0
+  };
+
--- /dev/null
+++ b/src/winfonts/winfnt.h
@@ -1,0 +1,146 @@
+/***************************************************************************/
+/*                                                                         */
+/*  winfnt.h                                                               */
+/*                                                                         */
+/*    FreeType font driver for Windows FNT/FON files                       */
+/*                                                                         */
+/*  Copyright 1996-2000 by                                                 */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used        */
+/*  modified and distributed under the terms of the FreeType project       */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#ifndef WINFNT_H
+#define WINFNT_H
+
+#include <freetype/internal/ftdriver.h>
+
+  typedef struct WinMZ_Header_
+  {
+    FT_UShort  magic;
+    /* skipped content */
+    FT_UShort  lfanew;
+  
+  } WinMZ_Header;
+
+
+
+  typedef struct WinNE_Header_
+  {
+    FT_UShort  magic;
+    /* skipped content */
+    FT_UShort  resource_tab_offset;
+    FT_UShort  rname_tab_offset;
+    
+  } WinNE_Header;
+
+
+
+  typedef struct WinNameInfo_
+  {
+    FT_UShort  offset;
+    FT_UShort  length;
+    FT_UShort  flags;
+    FT_UShort  id;
+    FT_UShort  handle;
+    FT_UShort  usage;
+    
+  } WinNameInfo;
+
+
+  typedef struct WinResourceInfo_
+  {
+    FT_UShort  type_id;
+    FT_UShort  count;
+  
+  } WinResourceInfo;
+
+#define  WINFNT_MZ_MAGIC  0x5A4D
+#define  WINFNT_NE_MAGIC  0x454E
+
+
+  typedef struct WinFNT_Header_
+  {
+    FT_UShort     version;
+    FT_ULong      file_size;
+    FT_Byte       copyright[60];
+    FT_UShort     file_type;
+    FT_UShort     nominal_point_size;
+    FT_UShort     vertical_resolution;
+    FT_UShort     horizontal_resolution;
+    FT_UShort     ascent;
+    FT_UShort     internal_leading;
+    FT_UShort     external_leading;
+    FT_Byte       italic;
+    FT_Byte       underline;
+    FT_Byte       strike_out;
+    FT_UShort     weight;
+    FT_Byte       charset;
+    FT_UShort     pixel_width;
+    FT_UShort     pixel_height;
+    FT_Byte       pitch_and_family;
+    FT_UShort     avg_width;
+    FT_UShort     max_width;
+    FT_Byte       first_char;
+    FT_Byte       last_char;
+    FT_Byte       default_char;
+    FT_Byte       break_char;
+    FT_UShort     bytes_per_row;
+    FT_ULong      device_offset;
+    FT_ULong      face_name_offset;
+    FT_ULong      bits_pointer;
+    FT_ULong      bits_offset;
+    FT_Byte       reserved;
+    FT_ULong      flags;
+    FT_UShort     A_space;
+    FT_UShort     B_space;
+    FT_UShort     C_space;
+    FT_UShort     color_table_offset;
+    FT_Byte       reserved2[4];
+  
+  } WinFNT_Header;
+
+
+  typedef struct FNT_Font_
+  {
+    FT_ULong       offset;
+    FT_Int         size_shift;
+    
+    WinFNT_Header  header;
+    
+    FT_Byte*       fnt_frame;
+    FT_ULong       fnt_size;
+    
+  } FNT_Font;
+
+
+  typedef struct FNT_SizeRec_
+  {
+    FT_SizeRec    root;
+    FNT_Font*     font;
+  
+  } FNT_SizeRec, *FNT_Size;
+
+
+
+  typedef struct FNT_FaceRec_
+  {
+    FT_FaceRec     root;
+    
+    FT_UInt        num_fonts;
+    FNT_Font*      fonts;
+
+    FT_CharMap     charmap_handle;    
+    FT_CharMapRec  charmap;  /* a single charmap per face */
+
+  } FNT_FaceRec, *FNT_Face;
+
+
+  FT_EXPORT_VAR(const FT_Driver_Class)  winfnt_driver_class;
+
+#endif /* WINFNT_H */