gdi32: Move CreateScalableFontResourceW to text.c.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c5d7140054
commit
0d35d2aa19
|
@ -5440,259 +5440,19 @@ DWORD WINAPI NtGdiGetGlyphOutline( HDC hdc, UINT ch, UINT format, GLYPHMETRICS *
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define NE_FFLAGS_LIBMODULE 0x8000
|
BOOL get_file_outline_text_metric( const WCHAR *path, OUTLINETEXTMETRICW *otm )
|
||||||
#define NE_OSFLAGS_WINDOWS 0x02
|
|
||||||
|
|
||||||
static const char dos_string[0x40] = "This is a TrueType resource file";
|
|
||||||
static const char FONTRES[] = {'F','O','N','T','R','E','S',':'};
|
|
||||||
|
|
||||||
#include <pshpack1.h>
|
|
||||||
struct fontdir
|
|
||||||
{
|
{
|
||||||
WORD num_of_resources;
|
|
||||||
WORD res_id;
|
|
||||||
WORD dfVersion;
|
|
||||||
DWORD dfSize;
|
|
||||||
CHAR dfCopyright[60];
|
|
||||||
WORD dfType;
|
|
||||||
WORD dfPoints;
|
|
||||||
WORD dfVertRes;
|
|
||||||
WORD dfHorizRes;
|
|
||||||
WORD dfAscent;
|
|
||||||
WORD dfInternalLeading;
|
|
||||||
WORD dfExternalLeading;
|
|
||||||
BYTE dfItalic;
|
|
||||||
BYTE dfUnderline;
|
|
||||||
BYTE dfStrikeOut;
|
|
||||||
WORD dfWeight;
|
|
||||||
BYTE dfCharSet;
|
|
||||||
WORD dfPixWidth;
|
|
||||||
WORD dfPixHeight;
|
|
||||||
BYTE dfPitchAndFamily;
|
|
||||||
WORD dfAvgWidth;
|
|
||||||
WORD dfMaxWidth;
|
|
||||||
BYTE dfFirstChar;
|
|
||||||
BYTE dfLastChar;
|
|
||||||
BYTE dfDefaultChar;
|
|
||||||
BYTE dfBreakChar;
|
|
||||||
WORD dfWidthBytes;
|
|
||||||
DWORD dfDevice;
|
|
||||||
DWORD dfFace;
|
|
||||||
DWORD dfReserved;
|
|
||||||
CHAR szFaceName[LF_FACESIZE];
|
|
||||||
};
|
|
||||||
#include <poppack.h>
|
|
||||||
|
|
||||||
#include <pshpack2.h>
|
|
||||||
|
|
||||||
struct ne_typeinfo
|
|
||||||
{
|
|
||||||
WORD type_id;
|
|
||||||
WORD count;
|
|
||||||
DWORD res;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ne_nameinfo
|
|
||||||
{
|
|
||||||
WORD off;
|
|
||||||
WORD len;
|
|
||||||
WORD flags;
|
|
||||||
WORD id;
|
|
||||||
DWORD res;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rsrc_tab
|
|
||||||
{
|
|
||||||
WORD align;
|
|
||||||
struct ne_typeinfo fontdir_type;
|
|
||||||
struct ne_nameinfo fontdir_name;
|
|
||||||
struct ne_typeinfo scalable_type;
|
|
||||||
struct ne_nameinfo scalable_name;
|
|
||||||
WORD end_of_rsrc;
|
|
||||||
BYTE fontdir_res_name[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <poppack.h>
|
|
||||||
|
|
||||||
static BOOL create_fot( const WCHAR *resource, const WCHAR *font_file, const struct fontdir *fontdir )
|
|
||||||
{
|
|
||||||
BOOL ret = FALSE;
|
|
||||||
HANDLE file;
|
|
||||||
DWORD size, written;
|
|
||||||
BYTE *ptr, *start;
|
|
||||||
BYTE import_name_len, res_name_len, non_res_name_len, font_file_len;
|
|
||||||
char *font_fileA, *last_part, *ext;
|
|
||||||
IMAGE_DOS_HEADER dos;
|
|
||||||
IMAGE_OS2_HEADER ne =
|
|
||||||
{
|
|
||||||
IMAGE_OS2_SIGNATURE, 5, 1, 0, 0, 0, NE_FFLAGS_LIBMODULE, 0,
|
|
||||||
0, 0, 0, 0, 0, 0,
|
|
||||||
0, sizeof(ne), sizeof(ne), 0, 0, 0, 0,
|
|
||||||
0, 4, 2, NE_OSFLAGS_WINDOWS, 0, 0, 0, 0, 0x300
|
|
||||||
};
|
|
||||||
struct rsrc_tab rsrc_tab =
|
|
||||||
{
|
|
||||||
4,
|
|
||||||
{ 0x8007, 1, 0 },
|
|
||||||
{ 0, 0, 0x0c50, 0x2c, 0 },
|
|
||||||
{ 0x80cc, 1, 0 },
|
|
||||||
{ 0, 0, 0x0c50, 0x8001, 0 },
|
|
||||||
0,
|
|
||||||
{ 7,'F','O','N','T','D','I','R'}
|
|
||||||
};
|
|
||||||
|
|
||||||
memset( &dos, 0, sizeof(dos) );
|
|
||||||
dos.e_magic = IMAGE_DOS_SIGNATURE;
|
|
||||||
dos.e_lfanew = sizeof(dos) + sizeof(dos_string);
|
|
||||||
|
|
||||||
/* import name is last part\0, resident name is last part without extension
|
|
||||||
non-resident name is "FONTRES:" + lfFaceName */
|
|
||||||
|
|
||||||
font_file_len = WideCharToMultiByte( CP_ACP, 0, font_file, -1, NULL, 0, NULL, NULL );
|
|
||||||
font_fileA = HeapAlloc( GetProcessHeap(), 0, font_file_len );
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, font_file, -1, font_fileA, font_file_len, NULL, NULL );
|
|
||||||
|
|
||||||
last_part = strrchr( font_fileA, '\\' );
|
|
||||||
if (last_part) last_part++;
|
|
||||||
else last_part = font_fileA;
|
|
||||||
import_name_len = strlen( last_part ) + 1;
|
|
||||||
|
|
||||||
ext = strchr( last_part, '.' );
|
|
||||||
if (ext) res_name_len = ext - last_part;
|
|
||||||
else res_name_len = import_name_len - 1;
|
|
||||||
|
|
||||||
non_res_name_len = sizeof( FONTRES ) + strlen( fontdir->szFaceName );
|
|
||||||
|
|
||||||
ne.ne_cbnrestab = 1 + non_res_name_len + 2 + 1; /* len + string + (WORD) ord_num + 1 byte eod */
|
|
||||||
ne.ne_restab = ne.ne_rsrctab + sizeof(rsrc_tab);
|
|
||||||
ne.ne_modtab = ne.ne_imptab = ne.ne_restab + 1 + res_name_len + 2 + 3; /* len + string + (WORD) ord_num + 3 bytes eod */
|
|
||||||
ne.ne_enttab = ne.ne_imptab + 1 + import_name_len; /* len + string */
|
|
||||||
ne.ne_cbenttab = 2;
|
|
||||||
ne.ne_nrestab = ne.ne_enttab + ne.ne_cbenttab + 2 + dos.e_lfanew; /* there are 2 bytes of 0 after entry tab */
|
|
||||||
|
|
||||||
rsrc_tab.scalable_name.off = (ne.ne_nrestab + ne.ne_cbnrestab + 0xf) >> 4;
|
|
||||||
rsrc_tab.scalable_name.len = (font_file_len + 0xf) >> 4;
|
|
||||||
rsrc_tab.fontdir_name.off = rsrc_tab.scalable_name.off + rsrc_tab.scalable_name.len;
|
|
||||||
rsrc_tab.fontdir_name.len = (fontdir->dfSize + 0xf) >> 4;
|
|
||||||
|
|
||||||
size = (rsrc_tab.fontdir_name.off + rsrc_tab.fontdir_name.len) << 4;
|
|
||||||
start = ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
|
|
||||||
|
|
||||||
if (!ptr)
|
|
||||||
{
|
|
||||||
HeapFree( GetProcessHeap(), 0, font_fileA );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy( ptr, &dos, sizeof(dos) );
|
|
||||||
memcpy( ptr + sizeof(dos), dos_string, sizeof(dos_string) );
|
|
||||||
memcpy( ptr + dos.e_lfanew, &ne, sizeof(ne) );
|
|
||||||
|
|
||||||
ptr = start + dos.e_lfanew + ne.ne_rsrctab;
|
|
||||||
memcpy( ptr, &rsrc_tab, sizeof(rsrc_tab) );
|
|
||||||
|
|
||||||
ptr = start + dos.e_lfanew + ne.ne_restab;
|
|
||||||
*ptr++ = res_name_len;
|
|
||||||
memcpy( ptr, last_part, res_name_len );
|
|
||||||
|
|
||||||
ptr = start + dos.e_lfanew + ne.ne_imptab;
|
|
||||||
*ptr++ = import_name_len;
|
|
||||||
memcpy( ptr, last_part, import_name_len );
|
|
||||||
|
|
||||||
ptr = start + ne.ne_nrestab;
|
|
||||||
*ptr++ = non_res_name_len;
|
|
||||||
memcpy( ptr, FONTRES, sizeof(FONTRES) );
|
|
||||||
memcpy( ptr + sizeof(FONTRES), fontdir->szFaceName, strlen( fontdir->szFaceName ) );
|
|
||||||
|
|
||||||
ptr = start + (rsrc_tab.scalable_name.off << 4);
|
|
||||||
memcpy( ptr, font_fileA, font_file_len );
|
|
||||||
|
|
||||||
ptr = start + (rsrc_tab.fontdir_name.off << 4);
|
|
||||||
memcpy( ptr, fontdir, fontdir->dfSize );
|
|
||||||
|
|
||||||
file = CreateFileW( resource, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
|
|
||||||
if (file != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
if (WriteFile( file, start, size, &written, NULL ) && written == size)
|
|
||||||
ret = TRUE;
|
|
||||||
CloseHandle( file );
|
|
||||||
}
|
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, start );
|
|
||||||
HeapFree( GetProcessHeap(), 0, font_fileA );
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* CreateScalableFontResourceW (GDI32.@)
|
|
||||||
*/
|
|
||||||
BOOL WINAPI CreateScalableFontResourceW( DWORD hidden, LPCWSTR resource_file,
|
|
||||||
LPCWSTR font_file, LPCWSTR font_path )
|
|
||||||
{
|
|
||||||
struct fontdir fontdir = { 0 };
|
|
||||||
struct gdi_font *font = NULL;
|
struct gdi_font *font = NULL;
|
||||||
WCHAR path[MAX_PATH];
|
|
||||||
|
|
||||||
TRACE("(%d, %s, %s, %s)\n", hidden, debugstr_w(resource_file),
|
if (!path || !font_funcs) return FALSE;
|
||||||
debugstr_w(font_file), debugstr_w(font_path) );
|
|
||||||
|
|
||||||
if (!font_funcs) return FALSE;
|
|
||||||
|
|
||||||
if (!font_file) goto done;
|
|
||||||
if (font_path && font_path[0])
|
|
||||||
{
|
|
||||||
int len = lstrlenW( font_path ) + lstrlenW( font_file ) + 2;
|
|
||||||
if (len > MAX_PATH) goto done;
|
|
||||||
lstrcpynW( path, font_path, MAX_PATH );
|
|
||||||
lstrcatW( path, L"\\" );
|
|
||||||
lstrcatW( path, font_file );
|
|
||||||
}
|
|
||||||
else if (!GetFullPathNameW( font_file, MAX_PATH, path, NULL )) goto done;
|
|
||||||
|
|
||||||
if (!(font = alloc_gdi_font( path, NULL, 0 ))) goto done;
|
if (!(font = alloc_gdi_font( path, NULL, 0 ))) goto done;
|
||||||
font->lf.lfHeight = 100;
|
font->lf.lfHeight = 100;
|
||||||
if (!font_funcs->load_font( font )) goto done;
|
if (!font_funcs->load_font( font )) goto done;
|
||||||
if (!font_funcs->set_outline_text_metrics( font )) goto done;
|
if (!font_funcs->set_outline_text_metrics( font )) goto done;
|
||||||
|
*otm = font->otm;
|
||||||
if (!(font->otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) goto done;
|
|
||||||
|
|
||||||
fontdir.num_of_resources = 1;
|
|
||||||
fontdir.res_id = 0;
|
|
||||||
fontdir.dfVersion = 0x200;
|
|
||||||
fontdir.dfSize = sizeof(fontdir);
|
|
||||||
strcpy( fontdir.dfCopyright, "Wine fontdir" );
|
|
||||||
fontdir.dfType = 0x4003; /* 0x0080 set if private */
|
|
||||||
fontdir.dfPoints = font->otm.otmEMSquare;
|
|
||||||
fontdir.dfVertRes = 72;
|
|
||||||
fontdir.dfHorizRes = 72;
|
|
||||||
fontdir.dfAscent = font->otm.otmTextMetrics.tmAscent;
|
|
||||||
fontdir.dfInternalLeading = font->otm.otmTextMetrics.tmInternalLeading;
|
|
||||||
fontdir.dfExternalLeading = font->otm.otmTextMetrics.tmExternalLeading;
|
|
||||||
fontdir.dfItalic = font->otm.otmTextMetrics.tmItalic;
|
|
||||||
fontdir.dfUnderline = font->otm.otmTextMetrics.tmUnderlined;
|
|
||||||
fontdir.dfStrikeOut = font->otm.otmTextMetrics.tmStruckOut;
|
|
||||||
fontdir.dfWeight = font->otm.otmTextMetrics.tmWeight;
|
|
||||||
fontdir.dfCharSet = font->otm.otmTextMetrics.tmCharSet;
|
|
||||||
fontdir.dfPixWidth = 0;
|
|
||||||
fontdir.dfPixHeight = font->otm.otmTextMetrics.tmHeight;
|
|
||||||
fontdir.dfPitchAndFamily = font->otm.otmTextMetrics.tmPitchAndFamily;
|
|
||||||
fontdir.dfAvgWidth = font->otm.otmTextMetrics.tmAveCharWidth;
|
|
||||||
fontdir.dfMaxWidth = font->otm.otmTextMetrics.tmMaxCharWidth;
|
|
||||||
fontdir.dfFirstChar = font->otm.otmTextMetrics.tmFirstChar;
|
|
||||||
fontdir.dfLastChar = font->otm.otmTextMetrics.tmLastChar;
|
|
||||||
fontdir.dfDefaultChar = font->otm.otmTextMetrics.tmDefaultChar;
|
|
||||||
fontdir.dfBreakChar = font->otm.otmTextMetrics.tmBreakChar;
|
|
||||||
fontdir.dfWidthBytes = 0;
|
|
||||||
fontdir.dfDevice = 0;
|
|
||||||
fontdir.dfFace = FIELD_OFFSET( struct fontdir, szFaceName );
|
|
||||||
fontdir.dfReserved = 0;
|
|
||||||
WideCharToMultiByte( CP_ACP, 0, (WCHAR *)font->otm.otmpFamilyName, -1,
|
|
||||||
fontdir.szFaceName, LF_FACESIZE, NULL, NULL );
|
|
||||||
free_gdi_font( font );
|
free_gdi_font( font );
|
||||||
|
return TRUE;
|
||||||
if (hidden) fontdir.dfType |= 0x80;
|
|
||||||
return create_fot( resource_file, font_file, &fontdir );
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (font) free_gdi_font( font );
|
if (font) free_gdi_font( font );
|
||||||
|
|
|
@ -283,6 +283,8 @@ extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void *bits,
|
||||||
UINT *usage ) DECLSPEC_HIDDEN;
|
UINT *usage ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL get_icm_profile( HDC hdc, BOOL allow_default, DWORD *size,
|
extern BOOL get_icm_profile( HDC hdc, BOOL allow_default, DWORD *size,
|
||||||
WCHAR *filename ) DECLSPEC_HIDDEN;
|
WCHAR *filename ) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL get_file_outline_text_metric( const WCHAR *path, OUTLINETEXTMETRICW *otm ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
||||||
static inline int get_dib_stride( int width, int bpp )
|
static inline int get_dib_stride( int width, int bpp )
|
||||||
{
|
{
|
||||||
|
|
|
@ -2333,6 +2333,257 @@ HANDLE WINAPI AddFontMemResourceEx( void *ptr, DWORD size, void *dv, DWORD *coun
|
||||||
return NtGdiAddFontMemResourceEx( ptr, size, dv, 0, count );
|
return NtGdiAddFontMemResourceEx( ptr, size, dv, 0, count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NE_FFLAGS_LIBMODULE 0x8000
|
||||||
|
#define NE_OSFLAGS_WINDOWS 0x02
|
||||||
|
|
||||||
|
static const char dos_string[0x40] = "This is a TrueType resource file";
|
||||||
|
static const char FONTRES[] = {'F','O','N','T','R','E','S',':'};
|
||||||
|
|
||||||
|
#include <pshpack1.h>
|
||||||
|
struct fontdir
|
||||||
|
{
|
||||||
|
WORD num_of_resources;
|
||||||
|
WORD res_id;
|
||||||
|
WORD dfVersion;
|
||||||
|
DWORD dfSize;
|
||||||
|
CHAR dfCopyright[60];
|
||||||
|
WORD dfType;
|
||||||
|
WORD dfPoints;
|
||||||
|
WORD dfVertRes;
|
||||||
|
WORD dfHorizRes;
|
||||||
|
WORD dfAscent;
|
||||||
|
WORD dfInternalLeading;
|
||||||
|
WORD dfExternalLeading;
|
||||||
|
BYTE dfItalic;
|
||||||
|
BYTE dfUnderline;
|
||||||
|
BYTE dfStrikeOut;
|
||||||
|
WORD dfWeight;
|
||||||
|
BYTE dfCharSet;
|
||||||
|
WORD dfPixWidth;
|
||||||
|
WORD dfPixHeight;
|
||||||
|
BYTE dfPitchAndFamily;
|
||||||
|
WORD dfAvgWidth;
|
||||||
|
WORD dfMaxWidth;
|
||||||
|
BYTE dfFirstChar;
|
||||||
|
BYTE dfLastChar;
|
||||||
|
BYTE dfDefaultChar;
|
||||||
|
BYTE dfBreakChar;
|
||||||
|
WORD dfWidthBytes;
|
||||||
|
DWORD dfDevice;
|
||||||
|
DWORD dfFace;
|
||||||
|
DWORD dfReserved;
|
||||||
|
CHAR szFaceName[LF_FACESIZE];
|
||||||
|
};
|
||||||
|
#include <poppack.h>
|
||||||
|
|
||||||
|
#include <pshpack2.h>
|
||||||
|
|
||||||
|
struct ne_typeinfo
|
||||||
|
{
|
||||||
|
WORD type_id;
|
||||||
|
WORD count;
|
||||||
|
DWORD res;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ne_nameinfo
|
||||||
|
{
|
||||||
|
WORD off;
|
||||||
|
WORD len;
|
||||||
|
WORD flags;
|
||||||
|
WORD id;
|
||||||
|
DWORD res;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rsrc_tab
|
||||||
|
{
|
||||||
|
WORD align;
|
||||||
|
struct ne_typeinfo fontdir_type;
|
||||||
|
struct ne_nameinfo fontdir_name;
|
||||||
|
struct ne_typeinfo scalable_type;
|
||||||
|
struct ne_nameinfo scalable_name;
|
||||||
|
WORD end_of_rsrc;
|
||||||
|
BYTE fontdir_res_name[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <poppack.h>
|
||||||
|
|
||||||
|
static BOOL create_fot( const WCHAR *resource, const WCHAR *font_file, const struct fontdir *fontdir )
|
||||||
|
{
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
HANDLE file;
|
||||||
|
DWORD size, written;
|
||||||
|
BYTE *ptr, *start;
|
||||||
|
BYTE import_name_len, res_name_len, non_res_name_len, font_file_len;
|
||||||
|
char *font_fileA, *last_part, *ext;
|
||||||
|
IMAGE_DOS_HEADER dos;
|
||||||
|
IMAGE_OS2_HEADER ne =
|
||||||
|
{
|
||||||
|
IMAGE_OS2_SIGNATURE, 5, 1, 0, 0, 0, NE_FFLAGS_LIBMODULE, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
0, sizeof(ne), sizeof(ne), 0, 0, 0, 0,
|
||||||
|
0, 4, 2, NE_OSFLAGS_WINDOWS, 0, 0, 0, 0, 0x300
|
||||||
|
};
|
||||||
|
struct rsrc_tab rsrc_tab =
|
||||||
|
{
|
||||||
|
4,
|
||||||
|
{ 0x8007, 1, 0 },
|
||||||
|
{ 0, 0, 0x0c50, 0x2c, 0 },
|
||||||
|
{ 0x80cc, 1, 0 },
|
||||||
|
{ 0, 0, 0x0c50, 0x8001, 0 },
|
||||||
|
0,
|
||||||
|
{ 7,'F','O','N','T','D','I','R'}
|
||||||
|
};
|
||||||
|
|
||||||
|
memset( &dos, 0, sizeof(dos) );
|
||||||
|
dos.e_magic = IMAGE_DOS_SIGNATURE;
|
||||||
|
dos.e_lfanew = sizeof(dos) + sizeof(dos_string);
|
||||||
|
|
||||||
|
/* import name is last part\0, resident name is last part without extension
|
||||||
|
non-resident name is "FONTRES:" + lfFaceName */
|
||||||
|
|
||||||
|
font_file_len = WideCharToMultiByte( CP_ACP, 0, font_file, -1, NULL, 0, NULL, NULL );
|
||||||
|
font_fileA = HeapAlloc( GetProcessHeap(), 0, font_file_len );
|
||||||
|
WideCharToMultiByte( CP_ACP, 0, font_file, -1, font_fileA, font_file_len, NULL, NULL );
|
||||||
|
|
||||||
|
last_part = strrchr( font_fileA, '\\' );
|
||||||
|
if (last_part) last_part++;
|
||||||
|
else last_part = font_fileA;
|
||||||
|
import_name_len = strlen( last_part ) + 1;
|
||||||
|
|
||||||
|
ext = strchr( last_part, '.' );
|
||||||
|
if (ext) res_name_len = ext - last_part;
|
||||||
|
else res_name_len = import_name_len - 1;
|
||||||
|
|
||||||
|
non_res_name_len = sizeof( FONTRES ) + strlen( fontdir->szFaceName );
|
||||||
|
|
||||||
|
ne.ne_cbnrestab = 1 + non_res_name_len + 2 + 1; /* len + string + (WORD) ord_num + 1 byte eod */
|
||||||
|
ne.ne_restab = ne.ne_rsrctab + sizeof(rsrc_tab);
|
||||||
|
ne.ne_modtab = ne.ne_imptab = ne.ne_restab + 1 + res_name_len + 2 + 3; /* len + string + (WORD) ord_num + 3 bytes eod */
|
||||||
|
ne.ne_enttab = ne.ne_imptab + 1 + import_name_len; /* len + string */
|
||||||
|
ne.ne_cbenttab = 2;
|
||||||
|
ne.ne_nrestab = ne.ne_enttab + ne.ne_cbenttab + 2 + dos.e_lfanew; /* there are 2 bytes of 0 after entry tab */
|
||||||
|
|
||||||
|
rsrc_tab.scalable_name.off = (ne.ne_nrestab + ne.ne_cbnrestab + 0xf) >> 4;
|
||||||
|
rsrc_tab.scalable_name.len = (font_file_len + 0xf) >> 4;
|
||||||
|
rsrc_tab.fontdir_name.off = rsrc_tab.scalable_name.off + rsrc_tab.scalable_name.len;
|
||||||
|
rsrc_tab.fontdir_name.len = (fontdir->dfSize + 0xf) >> 4;
|
||||||
|
|
||||||
|
size = (rsrc_tab.fontdir_name.off + rsrc_tab.fontdir_name.len) << 4;
|
||||||
|
start = ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, font_fileA );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy( ptr, &dos, sizeof(dos) );
|
||||||
|
memcpy( ptr + sizeof(dos), dos_string, sizeof(dos_string) );
|
||||||
|
memcpy( ptr + dos.e_lfanew, &ne, sizeof(ne) );
|
||||||
|
|
||||||
|
ptr = start + dos.e_lfanew + ne.ne_rsrctab;
|
||||||
|
memcpy( ptr, &rsrc_tab, sizeof(rsrc_tab) );
|
||||||
|
|
||||||
|
ptr = start + dos.e_lfanew + ne.ne_restab;
|
||||||
|
*ptr++ = res_name_len;
|
||||||
|
memcpy( ptr, last_part, res_name_len );
|
||||||
|
|
||||||
|
ptr = start + dos.e_lfanew + ne.ne_imptab;
|
||||||
|
*ptr++ = import_name_len;
|
||||||
|
memcpy( ptr, last_part, import_name_len );
|
||||||
|
|
||||||
|
ptr = start + ne.ne_nrestab;
|
||||||
|
*ptr++ = non_res_name_len;
|
||||||
|
memcpy( ptr, FONTRES, sizeof(FONTRES) );
|
||||||
|
memcpy( ptr + sizeof(FONTRES), fontdir->szFaceName, strlen( fontdir->szFaceName ) );
|
||||||
|
|
||||||
|
ptr = start + (rsrc_tab.scalable_name.off << 4);
|
||||||
|
memcpy( ptr, font_fileA, font_file_len );
|
||||||
|
|
||||||
|
ptr = start + (rsrc_tab.fontdir_name.off << 4);
|
||||||
|
memcpy( ptr, fontdir, fontdir->dfSize );
|
||||||
|
|
||||||
|
file = CreateFileW( resource, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||||
|
if (file != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (WriteFile( file, start, size, &written, NULL ) && written == size)
|
||||||
|
ret = TRUE;
|
||||||
|
CloseHandle( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree( GetProcessHeap(), 0, start );
|
||||||
|
HeapFree( GetProcessHeap(), 0, font_fileA );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* CreateScalableFontResourceW (GDI32.@)
|
||||||
|
*/
|
||||||
|
BOOL WINAPI CreateScalableFontResourceW( DWORD hidden, const WCHAR *resource_file,
|
||||||
|
const WCHAR *font_file, const WCHAR *font_path )
|
||||||
|
{
|
||||||
|
struct fontdir fontdir = { 0 };
|
||||||
|
OUTLINETEXTMETRICW otm;
|
||||||
|
WCHAR path[MAX_PATH];
|
||||||
|
|
||||||
|
TRACE("(%d, %s, %s, %s)\n", hidden, debugstr_w(resource_file),
|
||||||
|
debugstr_w(font_file), debugstr_w(font_path) );
|
||||||
|
|
||||||
|
if (!font_file) goto done;
|
||||||
|
if (font_path && font_path[0])
|
||||||
|
{
|
||||||
|
int len = lstrlenW( font_path ) + lstrlenW( font_file ) + 2;
|
||||||
|
if (len > MAX_PATH) goto done;
|
||||||
|
lstrcpynW( path, font_path, MAX_PATH );
|
||||||
|
lstrcatW( path, L"\\" );
|
||||||
|
lstrcatW( path, font_file );
|
||||||
|
}
|
||||||
|
else if (!GetFullPathNameW( font_file, MAX_PATH, path, NULL )) goto done;
|
||||||
|
if (!get_file_outline_text_metric( path, &otm )) goto done;
|
||||||
|
if (!(otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) goto done;
|
||||||
|
|
||||||
|
fontdir.num_of_resources = 1;
|
||||||
|
fontdir.res_id = 0;
|
||||||
|
fontdir.dfVersion = 0x200;
|
||||||
|
fontdir.dfSize = sizeof(fontdir);
|
||||||
|
strcpy( fontdir.dfCopyright, "Wine fontdir" );
|
||||||
|
fontdir.dfType = 0x4003; /* 0x0080 set if private */
|
||||||
|
fontdir.dfPoints = otm.otmEMSquare;
|
||||||
|
fontdir.dfVertRes = 72;
|
||||||
|
fontdir.dfHorizRes = 72;
|
||||||
|
fontdir.dfAscent = otm.otmTextMetrics.tmAscent;
|
||||||
|
fontdir.dfInternalLeading = otm.otmTextMetrics.tmInternalLeading;
|
||||||
|
fontdir.dfExternalLeading = otm.otmTextMetrics.tmExternalLeading;
|
||||||
|
fontdir.dfItalic = otm.otmTextMetrics.tmItalic;
|
||||||
|
fontdir.dfUnderline = otm.otmTextMetrics.tmUnderlined;
|
||||||
|
fontdir.dfStrikeOut = otm.otmTextMetrics.tmStruckOut;
|
||||||
|
fontdir.dfWeight = otm.otmTextMetrics.tmWeight;
|
||||||
|
fontdir.dfCharSet = otm.otmTextMetrics.tmCharSet;
|
||||||
|
fontdir.dfPixWidth = 0;
|
||||||
|
fontdir.dfPixHeight = otm.otmTextMetrics.tmHeight;
|
||||||
|
fontdir.dfPitchAndFamily = otm.otmTextMetrics.tmPitchAndFamily;
|
||||||
|
fontdir.dfAvgWidth = otm.otmTextMetrics.tmAveCharWidth;
|
||||||
|
fontdir.dfMaxWidth = otm.otmTextMetrics.tmMaxCharWidth;
|
||||||
|
fontdir.dfFirstChar = otm.otmTextMetrics.tmFirstChar;
|
||||||
|
fontdir.dfLastChar = otm.otmTextMetrics.tmLastChar;
|
||||||
|
fontdir.dfDefaultChar = otm.otmTextMetrics.tmDefaultChar;
|
||||||
|
fontdir.dfBreakChar = otm.otmTextMetrics.tmBreakChar;
|
||||||
|
fontdir.dfWidthBytes = 0;
|
||||||
|
fontdir.dfDevice = 0;
|
||||||
|
fontdir.dfFace = FIELD_OFFSET( struct fontdir, szFaceName );
|
||||||
|
fontdir.dfReserved = 0;
|
||||||
|
WideCharToMultiByte( CP_ACP, 0, (WCHAR *)otm.otmpFamilyName, -1,
|
||||||
|
fontdir.szFaceName, LF_FACESIZE, NULL, NULL );
|
||||||
|
|
||||||
|
if (hidden) fontdir.dfType |= 0x80;
|
||||||
|
return create_fot( resource_file, font_file, &fontdir );
|
||||||
|
|
||||||
|
done:
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static const CHARSETINFO charset_info[] = {
|
static const CHARSETINFO charset_info[] = {
|
||||||
/* ANSI */
|
/* ANSI */
|
||||||
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
|
{ ANSI_CHARSET, 1252, {{0,0,0,0},{FS_LATIN1,0}} },
|
||||||
|
|
Loading…
Reference in New Issue