gdi32: Implement GetFontFileInfo().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
parent
4d98658621
commit
6f7dfe2cea
|
@ -364,6 +364,12 @@ typedef struct {
|
|||
GdiFont *font;
|
||||
} CHILD_FONT;
|
||||
|
||||
struct font_fileinfo {
|
||||
FILETIME writetime;
|
||||
LARGE_INTEGER size;
|
||||
WCHAR path[1];
|
||||
};
|
||||
|
||||
struct tagGdiFont {
|
||||
struct list entry;
|
||||
struct list unused_entry;
|
||||
|
@ -400,6 +406,7 @@ struct tagGdiFont {
|
|||
const VOID *vert_feature;
|
||||
DWORD cache_num;
|
||||
DWORD instance_id;
|
||||
struct font_fileinfo *fileinfo;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
@ -4505,6 +4512,7 @@ static void free_font(GdiFont *font)
|
|||
HeapFree(GetProcessHeap(), 0, child);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, font->fileinfo);
|
||||
free_font_handle(font->instance_id);
|
||||
if (font->ft_face) pFT_Done_Face(font->ft_face);
|
||||
if (font->mapping) unmap_font_file( font->mapping );
|
||||
|
@ -5161,6 +5169,29 @@ static const VOID * get_GSUB_vert_feature(const GdiFont *font)
|
|||
return feature;
|
||||
}
|
||||
|
||||
static void fill_fileinfo_from_face( GdiFont *font, Face *face )
|
||||
{
|
||||
WIN32_FILE_ATTRIBUTE_DATA info;
|
||||
int len;
|
||||
|
||||
if (!face->file)
|
||||
{
|
||||
font->fileinfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*font->fileinfo));
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlenW(face->file);
|
||||
font->fileinfo = HeapAlloc(GetProcessHeap(), 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
|
||||
if (GetFileAttributesExW(face->file, GetFileExInfoStandard, &info))
|
||||
{
|
||||
font->fileinfo->writetime = info.ftLastWriteTime;
|
||||
font->fileinfo->size.QuadPart = (LONGLONG)info.nFileSizeHigh << 32 | info.nFileSizeLow;
|
||||
strcpyW(font->fileinfo->path, face->file);
|
||||
}
|
||||
else
|
||||
memset(&font->fileinfo, 0, sizeof(*font->fileinfo) + len * sizeof(WCHAR));
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* freetype_SelectFont
|
||||
*/
|
||||
|
@ -5555,6 +5586,7 @@ found_face:
|
|||
goto done;
|
||||
}
|
||||
|
||||
fill_fileinfo_from_face( ret, face );
|
||||
ret->ntmFlags = face->ntmFlags;
|
||||
|
||||
pick_charmap( ret->ft_face, ret->charset );
|
||||
|
@ -8238,7 +8270,7 @@ static BOOL freetype_GetFontRealizationInfo( PHYSDEV dev, void *ptr )
|
|||
return dev->funcs->pGetFontRealizationInfo( dev, ptr );
|
||||
}
|
||||
|
||||
FIXME("(%p, %p): stub!\n", physdev->font, info);
|
||||
TRACE("(%p, %p)\n", physdev->font, info);
|
||||
|
||||
info->flags = 1;
|
||||
if(FT_IS_SCALABLE(physdev->font->ft_face))
|
||||
|
@ -8255,6 +8287,33 @@ static BOOL freetype_GetFontRealizationInfo( PHYSDEV dev, void *ptr )
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* GetFontFileInfo (GDI32.@)
|
||||
*/
|
||||
BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_fileinfo *info, DWORD size, DWORD *needed )
|
||||
{
|
||||
struct font_handle_entry *entry = handle_entry( instance_id );
|
||||
const GdiFont *font;
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
font = entry->obj;
|
||||
*needed = sizeof(*info) + strlenW(font->fileinfo->path) * sizeof(WCHAR);
|
||||
if (*needed > size)
|
||||
{
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* path is included too */
|
||||
memcpy(info, font->fileinfo, *needed);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* Kerning support for TrueType fonts
|
||||
*/
|
||||
|
@ -8644,6 +8703,8 @@ static const struct gdi_dc_funcs freetype_funcs =
|
|||
|
||||
#else /* HAVE_FREETYPE */
|
||||
|
||||
struct font_fileinfo;
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
BOOL WineEngInit(void)
|
||||
|
@ -8687,4 +8748,13 @@ BOOL WINAPI GetRasterizerCaps( LPRASTERIZER_STATUS lprs, UINT cbNumBytes)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* GetFontFileInfo (GDI32.@)
|
||||
*/
|
||||
BOOL WINAPI GetFontFileInfo( DWORD instance_id, DWORD unknown, struct font_fileinfo *info, DWORD size, DWORD *needed)
|
||||
{
|
||||
*needed = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* HAVE_FREETYPE */
|
||||
|
|
|
@ -279,6 +279,7 @@
|
|||
@ stdcall GetEnhMetaFileW(wstr)
|
||||
# @ stub GetFontAssocStatus
|
||||
@ stdcall GetFontData(long long long ptr long)
|
||||
@ stdcall GetFontFileInfo(long long ptr long ptr)
|
||||
@ stdcall GetFontLanguageInfo(long)
|
||||
@ stdcall GetFontRealizationInfo(long ptr)
|
||||
@ stub GetFontResourceInfo
|
||||
|
|
|
@ -4177,14 +4177,14 @@ static void test_RealizationInfo(void)
|
|||
ok((info[0] & 0xf) == 1, "info[0] = %x for the system font\n", info[0]);
|
||||
ok(info[3] == 0xcccccccc, "structure longer than 3 dwords\n");
|
||||
|
||||
if (!is_truetype_font_installed("Arial"))
|
||||
if (!is_truetype_font_installed("Tahoma"))
|
||||
{
|
||||
skip("skipping GdiRealizationInfo with truetype font\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(&lf, 0, sizeof(lf));
|
||||
strcpy(lf.lfFaceName, "Arial");
|
||||
strcpy(lf.lfFaceName, "Tahoma");
|
||||
lf.lfHeight = 20;
|
||||
lf.lfWeight = FW_NORMAL;
|
||||
hfont = CreateFontIndirectA(&lf);
|
||||
|
@ -4238,12 +4238,19 @@ static void test_RealizationInfo(void)
|
|||
ok(info2[6] == 0xcccccccc, "structure longer than 6 dwords\n");
|
||||
|
||||
/* Test GetFontFileInfo() */
|
||||
if (pGetFontFileInfo) {
|
||||
/* invalid font id */
|
||||
SetLastError(0xdeadbeef);
|
||||
r = pGetFontFileInfo(0xabababab, 0, &file_info, sizeof(file_info), &needed);
|
||||
ok(r == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "ret %d gle %d\n", r, GetLastError());
|
||||
|
||||
needed = 0;
|
||||
r = pGetFontFileInfo(fri->instance_id, 0, &file_info, sizeof(file_info), &needed);
|
||||
ok(r != 0 || GetLastError() == ERROR_NOACCESS, "ret %d gle %d\n", r, GetLastError());
|
||||
|
||||
if (r)
|
||||
{
|
||||
ok(needed > 0 && needed < sizeof(file_info), "got needed size %u\n", needed);
|
||||
|
||||
h = CreateFileW(file_info.path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
ok(h != INVALID_HANDLE_VALUE, "Unable to open file %d\n", GetLastError());
|
||||
|
||||
|
@ -4256,8 +4263,14 @@ static void test_RealizationInfo(void)
|
|||
ReadFile(h, file, sizeof(file), &read, NULL);
|
||||
CloseHandle(h);
|
||||
have_file = TRUE;
|
||||
|
||||
/* shorter buffer */
|
||||
SetLastError(0xdeadbeef);
|
||||
r = pGetFontFileInfo(fri->instance_id, 0, &file_info, needed - 1, &needed);
|
||||
ok(r == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "ret %d gle %d\n", r, GetLastError());
|
||||
}
|
||||
|
||||
if (pGetFontFileData) {
|
||||
/* Get bytes 2 - 16 using GetFontFileData */
|
||||
r = pGetFontFileData(fri->instance_id, 0, 2, data, sizeof(data));
|
||||
ok(r != 0, "ret 0 gle %d\n", GetLastError());
|
||||
|
|
Loading…
Reference in New Issue