From cd43ff167bd85d39aeb31ab41b6ccef29e7dfafe Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 11 Jun 2010 19:39:40 +0400 Subject: [PATCH] gdi32: Add CreateFontIndirectEx implementation. --- dlls/gdi32/font.c | 78 +++++++++++++++++++++++++++++++++++------ dlls/gdi32/gdi32.spec | 4 +-- dlls/gdi32/tests/font.c | 34 ++++++++++++++++++ include/wingdi.h | 27 ++++++++++++++ 4 files changed, 130 insertions(+), 13 deletions(-) diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c index 17fb381a612..637c7d6c6b1 100644 --- a/dlls/gdi32/font.c +++ b/dlls/gdi32/font.c @@ -180,7 +180,7 @@ static void FONT_LogFontWToA( const LOGFONTW *fontW, LPLOGFONTA fontA ) static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEXA fontA ) { - FONT_LogFontWToA( (const LOGFONTW *)fontW, (LPLOGFONTA)fontA); + FONT_LogFontWToA( &fontW->elfLogFont, &fontA->elfLogFont ); WideCharToMultiByte( CP_ACP, 0, fontW->elfFullName, -1, (LPSTR) fontA->elfFullName, LF_FULLFACESIZE, NULL, NULL ); @@ -193,6 +193,21 @@ static void FONT_EnumLogFontExWToA( const ENUMLOGFONTEXW *fontW, LPENUMLOGFONTEX fontA->elfScript[LF_FACESIZE-1] = '\0'; } +static void FONT_EnumLogFontExAToW( const ENUMLOGFONTEXA *fontA, LPENUMLOGFONTEXW fontW ) +{ + FONT_LogFontAToW( &fontA->elfLogFont, &fontW->elfLogFont ); + + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)fontA->elfFullName, -1, + fontW->elfFullName, LF_FULLFACESIZE ); + fontW->elfFullName[LF_FULLFACESIZE-1] = '\0'; + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)fontA->elfStyle, -1, + fontW->elfStyle, LF_FACESIZE ); + fontW->elfStyle[LF_FACESIZE-1] = '\0'; + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)fontA->elfScript, -1, + fontW->elfScript, LF_FACESIZE ); + fontW->elfScript[LF_FACESIZE-1] = '\0'; +} + /*********************************************************************** * TEXTMETRIC conversion functions. */ @@ -287,30 +302,42 @@ static LPWSTR FONT_mbtowc(HDC hdc, LPCSTR str, INT count, INT *plenW, UINT *pCP) return strW; } - /*********************************************************************** - * CreateFontIndirectA (GDI32.@) + * CreateFontIndirectExA (GDI32.@) */ -HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA ) +HFONT WINAPI CreateFontIndirectExA( const ENUMLOGFONTEXDVA *penumexA ) { - LOGFONTW lfW; + ENUMLOGFONTEXDVW enumexW; - if (!plfA) return 0; + if (!penumexA) return 0; - FONT_LogFontAToW( plfA, &lfW ); - return CreateFontIndirectW( &lfW ); + FONT_EnumLogFontExAToW( &penumexA->elfEnumLogfontEx, &enumexW.elfEnumLogfontEx ); + enumexW.elfDesignVector = penumexA->elfDesignVector; + return CreateFontIndirectExW( &enumexW ); } /*********************************************************************** - * CreateFontIndirectW (GDI32.@) + * CreateFontIndirectExA (GDI32.@) */ -HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf ) +HFONT WINAPI CreateFontIndirectExW( const ENUMLOGFONTEXDVW *penumex ) { HFONT hFont; FONTOBJ *fontPtr; + const LOGFONTW *plf; - if (!plf) return 0; + if (!penumex) return 0; + if (penumex->elfEnumLogfontEx.elfFullName[0] || + penumex->elfEnumLogfontEx.elfStyle[0] || + penumex->elfEnumLogfontEx.elfScript[0]) + { + FIXME("some fields ignored. fullname=%s, style=%s, script=%s\n", + debugstr_w(penumex->elfEnumLogfontEx.elfFullName), + debugstr_w(penumex->elfEnumLogfontEx.elfStyle), + debugstr_w(penumex->elfEnumLogfontEx.elfScript)); + } + + plf = &penumex->elfEnumLogfontEx.elfLogFont; if (!(fontPtr = HeapAlloc( GetProcessHeap(), 0, sizeof(*fontPtr) ))) return 0; fontPtr->logfont = *plf; @@ -344,6 +371,35 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf ) return hFont; } +/*********************************************************************** + * CreateFontIndirectA (GDI32.@) + */ +HFONT WINAPI CreateFontIndirectA( const LOGFONTA *plfA ) +{ + LOGFONTW lfW; + + if (!plfA) return 0; + + FONT_LogFontAToW( plfA, &lfW ); + return CreateFontIndirectW( &lfW ); +} + +/*********************************************************************** + * CreateFontIndirectW (GDI32.@) + */ +HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf ) +{ + ENUMLOGFONTEXDVW exdv; + + if (!plf) return 0; + + exdv.elfEnumLogfontEx.elfLogFont = *plf; + exdv.elfEnumLogfontEx.elfFullName[0] = 0; + exdv.elfEnumLogfontEx.elfStyle[0] = 0; + exdv.elfEnumLogfontEx.elfScript[0] = 0; + return CreateFontIndirectExW( &exdv ); +} + /************************************************************************* * CreateFontA (GDI32.@) */ diff --git a/dlls/gdi32/gdi32.spec b/dlls/gdi32/gdi32.spec index e33a7ae8afe..d3843e6788a 100644 --- a/dlls/gdi32/gdi32.spec +++ b/dlls/gdi32/gdi32.spec @@ -58,8 +58,8 @@ @ stdcall CreateEnhMetaFileW(long wstr ptr wstr) @ stdcall CreateFontA(long long long long long long long long long long long long long str) @ stdcall CreateFontIndirectA(ptr) -# @ stub CreateFontIndirectExA -# @ stub CreateFontIndirectExW +@ stdcall CreateFontIndirectExA(ptr) +@ stdcall CreateFontIndirectExW(ptr) @ stdcall CreateFontIndirectW(ptr) @ stdcall CreateFontW(long long long long long long long long long long long long long wstr) @ stdcall CreateHalftonePalette(long) diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 6ef98c89e6d..d89132db441 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -43,6 +43,7 @@ DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs); DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags); DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags); BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *); +HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *); static HMODULE hgdi32 = 0; @@ -57,6 +58,7 @@ static void init(void) pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA"); pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW"); pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo"); + pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA"); } static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) @@ -3109,6 +3111,37 @@ static void test_CreateFontIndirect(void) } } +static void test_CreateFontIndirectEx(void) +{ + ENUMLOGFONTEXDVA lfex; + HFONT hfont; + + if (!pCreateFontIndirectExA) + { + win_skip("CreateFontIndirectExA is not available\n"); + return; + } + + if (!is_truetype_font_installed("Arial")) + { + skip("Arial is not installed\n"); + return; + } + + SetLastError(0xdeadbeef); + hfont = pCreateFontIndirectExA(NULL); + ok(hfont == NULL, "got %p\n", hfont); + ok(GetLastError() == 0xdeadbeef, "got error %d\n", GetLastError()); + + memset(&lfex, 0, sizeof(lfex)); + lstrcpyA(lfex.elfEnumLogfontEx.elfLogFont.lfFaceName, "Arial"); + hfont = pCreateFontIndirectExA(&lfex); + ok(hfont != 0, "CreateFontIndirectEx failed\n"); + if (hfont) + check_font("Arial", &lfex.elfEnumLogfontEx.elfLogFont, hfont); + DeleteObject(hfont); +} + START_TEST(font) { init(); @@ -3155,5 +3188,6 @@ START_TEST(font) test_GetTextMetrics2("Arial", -55); test_GetTextMetrics2("Arial", -110); test_CreateFontIndirect(); + test_CreateFontIndirectEx(); test_oemcharset(); } diff --git a/include/wingdi.h b/include/wingdi.h index 99fd2bcdc4e..e7aafb2696e 100644 --- a/include/wingdi.h +++ b/include/wingdi.h @@ -610,6 +610,30 @@ typedef struct DECL_WINELIB_TYPE_AW(ENUMLOGFONTEX) DECL_WINELIB_TYPE_AW(LPENUMLOGFONTEX) +#define MM_MAX_NUMAXES 16 + +typedef struct +{ + DWORD dvReserved; + DWORD dvNumAxes; + LONG dvValues[MM_MAX_NUMAXES]; +} DESIGNVECTOR, *PDESIGNVECTOR; + +typedef struct +{ + ENUMLOGFONTEXA elfEnumLogfontEx; + DESIGNVECTOR elfDesignVector; +} ENUMLOGFONTEXDVA, *PENUMLOGFONTEXDVA; + +typedef struct +{ + ENUMLOGFONTEXW elfEnumLogfontEx; + DESIGNVECTOR elfDesignVector; +} ENUMLOGFONTEXDVW, *PENUMLOGFONTEXDVW; + +DECL_WINELIB_TYPE_AW(ENUMLOGFONTEXDV) +DECL_WINELIB_TYPE_AW(PENUMLOGFONTEXDV) + /* * The FONTSIGNATURE tells which Unicode ranges and which code pages * have glyphs in a font. @@ -3356,6 +3380,9 @@ WINGDIAPI HFONT WINAPI CreateFontW(INT,INT,INT,INT,INT,DWORD,DWORD,DWORD,D WINGDIAPI HFONT WINAPI CreateFontIndirectA(const LOGFONTA*); WINGDIAPI HFONT WINAPI CreateFontIndirectW(const LOGFONTW*); #define CreateFontIndirect WINELIB_NAME_AW(CreateFontIndirect) +WINGDIAPI HFONT WINAPI CreateFontIndirectExA(const ENUMLOGFONTEXDVA*); +WINGDIAPI HFONT WINAPI CreateFontIndirectExW(const ENUMLOGFONTEXDVW*); +#define CreateFontIndirectEx WINELIB_NAME_AW(CreateFontIndirectEx) WINGDIAPI HPALETTE WINAPI CreateHalftonePalette(HDC); WINGDIAPI HBRUSH WINAPI CreateHatchBrush(INT,COLORREF); WINGDIAPI HDC WINAPI CreateICA(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);