* src/winfonts/winfnt.h: Add necessary structures for PE resource
parsing. (WinPE32_HeaderRec): New structure. (WinPE32_SectionRec): New structure. (WinPE_RsrcDirRec): New structure. (WinPE_RsrcDirEntryRec): New structure. (WinPE_RsrcDataEntryRec): New structure. (FNT_FontRec): Remove unused `size_shift' field. * src/winfonts/winfnt.c (fnt_face_get_dll_font): Add support for loading bitmap .fon files in PE format.
This commit is contained in:
parent
08a645d833
commit
ab1604bd6b
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2006-06-16 Dmitry Timoshkov <dmitry@codeweavers.com>
|
||||
|
||||
* src/winfonts/winfnt.h: Add necessary structures for PE resource
|
||||
parsing.
|
||||
(WinPE32_HeaderRec): New structure.
|
||||
(WinPE32_SectionRec): New structure.
|
||||
(WinPE_RsrcDirRec): New structure.
|
||||
(WinPE_RsrcDirEntryRec): New structure.
|
||||
(WinPE_RsrcDataEntryRec): New structure.
|
||||
(FNT_FontRec): Remove unused `size_shift' field.
|
||||
|
||||
* src/winfonts/winfnt.c (fnt_face_get_dll_font): Add support for
|
||||
loading bitmap .fon files in PE format.
|
||||
|
||||
2006-06-15 Dmitry Timoshkov <dmitry@codeweavers.com>
|
||||
|
||||
* builds/win32/ftdebug.c: Unify debug level handling with other
|
||||
|
@ -6391,7 +6391,7 @@
|
||||
* include/freetype/internal/fnttypes.h (WinFNT_HeaderRec): Increase
|
||||
size of `reserved2' to avoid memory overwrites.
|
||||
|
||||
2003-01-08 Huw Dawies <huw@codeweavers.com>
|
||||
2003-01-08 Huw Davies <huw@codeweavers.com>
|
||||
|
||||
* src/winfonts/winfnt.c (winfnt_header_fields): Read 16 bytes into
|
||||
`reserved2', not `reserved'.
|
||||
|
@ -32,6 +32,9 @@ CHANGES BETWEEN 2.3.5 and 2.3.4
|
||||
out whether a given TrueType font uses patented bytecode
|
||||
instructions.
|
||||
|
||||
- Support for Windows FON files in PE format has been contributed
|
||||
by Dmitry Timoshkov.
|
||||
|
||||
|
||||
III. MISCELLANEOUS
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* Copyright 2003 Huw D M Davies for Codeweavers */
|
||||
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
/* modified, and distributed under the terms of the FreeType project */
|
||||
@ -62,6 +64,80 @@
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winpe32_header_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE WinPE32_HeaderRec
|
||||
|
||||
FT_FRAME_START( 248 ),
|
||||
FT_FRAME_ULONG_LE ( magic ), /* PE00 */
|
||||
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_SKIP_BYTES( 110 ),
|
||||
FT_FRAME_ULONG_LE ( rsrc_virtual_address ),
|
||||
FT_FRAME_ULONG_LE ( rsrc_size ),
|
||||
FT_FRAME_SKIP_BYTES( 104 ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winpe32_section_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE WinPE32_SectionRec
|
||||
|
||||
FT_FRAME_START( 40 ),
|
||||
FT_FRAME_BYTES ( name, 8 ),
|
||||
FT_FRAME_SKIP_BYTES( 4 ),
|
||||
FT_FRAME_ULONG_LE ( virtual_address ),
|
||||
FT_FRAME_ULONG_LE ( size_of_raw_data ),
|
||||
FT_FRAME_ULONG_LE ( pointer_to_raw_data ),
|
||||
FT_FRAME_SKIP_BYTES( 16 ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winpe_rsrc_dir_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE WinPE_RsrcDirRec
|
||||
|
||||
FT_FRAME_START( 16 ),
|
||||
FT_FRAME_ULONG_LE ( characteristics ),
|
||||
FT_FRAME_ULONG_LE ( time_date_stamp ),
|
||||
FT_FRAME_USHORT_LE( major_version ),
|
||||
FT_FRAME_USHORT_LE( minor_version ),
|
||||
FT_FRAME_USHORT_LE( number_of_named_entries ),
|
||||
FT_FRAME_USHORT_LE( number_of_id_entries ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winpe_rsrc_dir_entry_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE WinPE_RsrcDirEntryRec
|
||||
|
||||
FT_FRAME_START( 8 ),
|
||||
FT_FRAME_ULONG_LE( name ),
|
||||
FT_FRAME_ULONG_LE( offset ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winpe_rsrc_data_entry_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
#define FT_STRUCTURE WinPE_RsrcDataEntryRec
|
||||
|
||||
FT_FRAME_START( 16 ),
|
||||
FT_FRAME_ULONG_LE( offset_to_data ),
|
||||
FT_FRAME_ULONG_LE( size ),
|
||||
FT_FRAME_ULONG_LE( code_page ),
|
||||
FT_FRAME_ULONG_LE( reserved ),
|
||||
FT_FRAME_END
|
||||
};
|
||||
|
||||
static const FT_Frame_Field winfnt_header_fields[] =
|
||||
{
|
||||
#undef FT_STRUCTURE
|
||||
@ -214,6 +290,8 @@
|
||||
WinNE_HeaderRec ne_header;
|
||||
|
||||
|
||||
FT_TRACE2(( "MZ signature found\n" ));
|
||||
|
||||
if ( FT_STREAM_SEEK( mz_header.lfanew ) ||
|
||||
FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )
|
||||
goto Exit;
|
||||
@ -229,6 +307,8 @@
|
||||
FT_ULong font_offset = 0;
|
||||
|
||||
|
||||
FT_TRACE2(( "NE signature found\n" ));
|
||||
|
||||
if ( FT_STREAM_SEEK( res_offset ) ||
|
||||
FT_FRAME_ENTER( ne_header.rname_tab_offset -
|
||||
ne_header.resource_tab_offset ) )
|
||||
@ -291,9 +371,8 @@
|
||||
FT_FRAME_ENTER( 12 ) )
|
||||
goto Fail;
|
||||
|
||||
face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
|
||||
face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
|
||||
face->font->size_shift = size_shift;
|
||||
face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
|
||||
face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
|
||||
|
||||
stream->cursor += 8;
|
||||
|
||||
@ -301,6 +380,181 @@
|
||||
|
||||
error = fnt_font_load( face->font, stream );
|
||||
}
|
||||
else if ( ne_header.magic == WINFNT_PE_MAGIC )
|
||||
{
|
||||
WinPE32_HeaderRec pe32_header;
|
||||
WinPE32_SectionRec pe32_section;
|
||||
WinPE_RsrcDirRec root_dir, name_dir, lang_dir;
|
||||
WinPE_RsrcDirEntryRec dir_entry1, dir_entry2, dir_entry3;
|
||||
WinPE_RsrcDataEntryRec data_entry;
|
||||
|
||||
FT_Long root_dir_offset, name_dir_offset, lang_dir_offset;
|
||||
FT_UShort i, j, k;
|
||||
|
||||
|
||||
FT_TRACE2(( "PE signature found\n" ));
|
||||
|
||||
if ( FT_STREAM_SEEK( mz_header.lfanew ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) )
|
||||
goto Exit;
|
||||
|
||||
FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, "
|
||||
"size_of_optional_header %02x\n"
|
||||
"magic32 %02x, rsrc_virtual_address %04lx, "
|
||||
"rsrc_size %04lx\n",
|
||||
pe32_header.magic, pe32_header.machine,
|
||||
pe32_header.number_of_sections,
|
||||
pe32_header.size_of_optional_header,
|
||||
pe32_header.magic32, pe32_header.rsrc_virtual_address,
|
||||
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 )
|
||||
{
|
||||
error = FNT_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
face->root.num_faces = 0;
|
||||
|
||||
for ( i = 0; i < pe32_header.number_of_sections; i++ )
|
||||
{
|
||||
if ( FT_STREAM_READ_FIELDS( winpe32_section_fields,
|
||||
&pe32_section ) )
|
||||
goto Exit;
|
||||
|
||||
FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n",
|
||||
pe32_section.name, pe32_section.virtual_address,
|
||||
pe32_section.size_of_raw_data,
|
||||
pe32_section.pointer_to_raw_data ));
|
||||
|
||||
if ( pe32_header.rsrc_virtual_address ==
|
||||
pe32_section.virtual_address )
|
||||
goto Found_rsrc_section;
|
||||
}
|
||||
|
||||
error = FNT_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
|
||||
Found_rsrc_section:
|
||||
FT_TRACE2(( "found resources section %.8s\n", pe32_section.name ));
|
||||
|
||||
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) )
|
||||
goto Exit;
|
||||
|
||||
root_dir_offset = pe32_section.pointer_to_raw_data;
|
||||
|
||||
for ( i = 0; i < root_dir.number_of_named_entries +
|
||||
root_dir.number_of_id_entries; i++ )
|
||||
{
|
||||
if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
|
||||
&dir_entry1 ) )
|
||||
goto Exit;
|
||||
|
||||
if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
|
||||
{
|
||||
error = FNT_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
dir_entry1.offset &= ~0x80000000UL;
|
||||
|
||||
name_dir_offset = pe32_section.pointer_to_raw_data +
|
||||
dir_entry1.offset;
|
||||
|
||||
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
|
||||
dir_entry1.offset ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) )
|
||||
goto Exit;
|
||||
|
||||
for ( j = 0; j < name_dir.number_of_named_entries +
|
||||
name_dir.number_of_id_entries; j++ )
|
||||
{
|
||||
if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
|
||||
&dir_entry2 ) )
|
||||
goto Exit;
|
||||
|
||||
if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
|
||||
{
|
||||
error = FNT_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
dir_entry2.offset &= ~0x80000000UL;
|
||||
|
||||
lang_dir_offset = pe32_section.pointer_to_raw_data +
|
||||
dir_entry2.offset;
|
||||
|
||||
if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
|
||||
dir_entry2.offset ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) )
|
||||
goto Exit;
|
||||
|
||||
for ( k = 0; k < lang_dir.number_of_named_entries +
|
||||
lang_dir.number_of_id_entries; k++ )
|
||||
{
|
||||
if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
|
||||
&dir_entry3 ) )
|
||||
goto Exit;
|
||||
|
||||
if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ )
|
||||
{
|
||||
error = FNT_Err_Invalid_File_Format;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if ( dir_entry1.name == 8 /* RT_FONT */ )
|
||||
{
|
||||
if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) ||
|
||||
FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields,
|
||||
&data_entry ) )
|
||||
goto Exit;
|
||||
|
||||
FT_TRACE2(( "found font #%lu, offset %04lx, "
|
||||
"size %04lx, cp %lu\n",
|
||||
dir_entry2.name,
|
||||
pe32_section.pointer_to_raw_data +
|
||||
data_entry.offset_to_data -
|
||||
pe32_section.virtual_address,
|
||||
data_entry.size, data_entry.code_page ));
|
||||
|
||||
if ( face_index == face->root.num_faces )
|
||||
{
|
||||
if ( FT_NEW( face->font ) )
|
||||
goto Exit;
|
||||
|
||||
face->font->offset = pe32_section.pointer_to_raw_data +
|
||||
data_entry.offset_to_data -
|
||||
pe32_section.virtual_address;
|
||||
face->font->fnt_size = data_entry.size;
|
||||
|
||||
error = fnt_font_load( face->font, stream );
|
||||
if ( error )
|
||||
FT_TRACE2(( "font #%lu load error %d\n",
|
||||
dir_entry2.name, error ));
|
||||
else
|
||||
FT_TRACE2(( "font #%lu successfully loaded\n",
|
||||
dir_entry2.name ));
|
||||
}
|
||||
|
||||
face->root.num_faces++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( face_index >= face->root.num_faces )
|
||||
{
|
||||
error = FNT_Err_Bad_Argument;
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
||||
Fail:
|
||||
|
@ -4,8 +4,9 @@
|
||||
/* */
|
||||
/* FreeType font driver for Windows FNT/FON files */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2007 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* Copyright 2007 Dmitry Timoshkov for Codeweavers */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
/* modified, and distributed under the terms of the FreeType project */
|
||||
@ -46,6 +47,65 @@ FT_BEGIN_HEADER
|
||||
} WinNE_HeaderRec;
|
||||
|
||||
|
||||
typedef struct WinPE32_HeaderRec_
|
||||
{
|
||||
FT_ULong magic;
|
||||
FT_UShort machine;
|
||||
FT_UShort number_of_sections;
|
||||
/* skipped content */
|
||||
FT_UShort size_of_optional_header;
|
||||
/* skipped content */
|
||||
FT_UShort magic32;
|
||||
/* skipped content */
|
||||
FT_ULong rsrc_virtual_address;
|
||||
FT_ULong rsrc_size;
|
||||
/* skipped content */
|
||||
|
||||
} WinPE32_HeaderRec;
|
||||
|
||||
|
||||
typedef struct WinPE32_SectionRec_
|
||||
{
|
||||
FT_Byte name[8];
|
||||
/* skipped content */
|
||||
FT_ULong virtual_address;
|
||||
FT_ULong size_of_raw_data;
|
||||
FT_ULong pointer_to_raw_data;
|
||||
/* skipped content */
|
||||
|
||||
} WinPE32_SectionRec;
|
||||
|
||||
|
||||
typedef struct WinPE_RsrcDirRec_
|
||||
{
|
||||
FT_ULong characteristics;
|
||||
FT_ULong time_date_stamp;
|
||||
FT_UShort major_version;
|
||||
FT_UShort minor_version;
|
||||
FT_UShort number_of_named_entries;
|
||||
FT_UShort number_of_id_entries;
|
||||
|
||||
} WinPE_RsrcDirRec;
|
||||
|
||||
|
||||
typedef struct WinPE_RsrcDirEntryRec_
|
||||
{
|
||||
FT_ULong name;
|
||||
FT_ULong offset;
|
||||
|
||||
} WinPE_RsrcDirEntryRec;
|
||||
|
||||
|
||||
typedef struct WinPE_RsrcDataEntryRec_
|
||||
{
|
||||
FT_ULong offset_to_data;
|
||||
FT_ULong size;
|
||||
FT_ULong code_page;
|
||||
FT_ULong reserved;
|
||||
|
||||
} WinPE_RsrcDataEntryRec;
|
||||
|
||||
|
||||
typedef struct WinNameInfoRec_
|
||||
{
|
||||
FT_UShort offset;
|
||||
@ -68,12 +128,12 @@ FT_BEGIN_HEADER
|
||||
|
||||
#define WINFNT_MZ_MAGIC 0x5A4D
|
||||
#define WINFNT_NE_MAGIC 0x454E
|
||||
#define WINFNT_PE_MAGIC 0x4550
|
||||
|
||||
|
||||
typedef struct FNT_FontRec_
|
||||
{
|
||||
FT_ULong offset;
|
||||
FT_Int size_shift;
|
||||
|
||||
FT_WinFNT_HeaderRec header;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user