gdi32: Implement GetCharWidthFloat().

Needed by Cygwin's mintty.exe.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Zebediah Figura 2019-09-26 09:17:03 -05:00 committed by Alexandre Julliard
parent 1692f90c23
commit 068093f1aa
2 changed files with 94 additions and 9 deletions

View File

@ -36,6 +36,7 @@
#include "winreg.h"
#include "gdi_private.h"
#include "wine/exception.h"
#include "wine/heap.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@ -3471,23 +3472,61 @@ done:
/*************************************************************************
* GetCharWidthFloatA [GDI32.@]
*/
BOOL WINAPI GetCharWidthFloatA(HDC hdc, UINT iFirstChar,
UINT iLastChar, PFLOAT pxBuffer)
BOOL WINAPI GetCharWidthFloatA( HDC hdc, UINT first, UINT last, float *buffer )
{
FIXME("%p, %u, %u, %p: stub!\n", hdc, iFirstChar, iLastChar, pxBuffer);
return FALSE;
WCHAR *wstr;
int i, wlen;
char *str;
if (!(str = FONT_GetCharsByRangeA( hdc, first, last, &i )))
return FALSE;
wstr = FONT_mbtowc( hdc, str, i, &wlen, NULL );
heap_free(str);
for (i = 0; i < wlen; ++i)
{
if (!GetCharWidthFloatW( hdc, wstr[i], wstr[i], &buffer[i] ))
{
heap_free(wstr);
return FALSE;
}
}
heap_free(wstr);
return TRUE;
}
/*************************************************************************
* GetCharWidthFloatW [GDI32.@]
*/
BOOL WINAPI GetCharWidthFloatW(HDC hdc, UINT iFirstChar,
UINT iLastChar, PFLOAT pxBuffer)
BOOL WINAPI GetCharWidthFloatW( HDC hdc, UINT first, UINT last, float *buffer )
{
FIXME("%p, %u, %u, %p: stub!\n", hdc, iFirstChar, iLastChar, pxBuffer);
return FALSE;
}
DC *dc = get_dc_ptr( hdc );
int *ibuffer;
PHYSDEV dev;
BOOL ret;
UINT i;
TRACE("dc %p, first %#x, last %#x, buffer %p\n", dc, first, last, buffer);
if (!dc) return FALSE;
if (!(ibuffer = heap_alloc( (last - first + 1) * sizeof(int) )))
{
release_dc_ptr( dc );
return FALSE;
}
dev = GET_DC_PHYSDEV( dc, pGetCharWidth );
if ((ret = dev->funcs->pGetCharWidth( dev, first, last, ibuffer )))
{
float scale = fabs( dc->xformVport2World.eM11 ) / 16.0f;
for (i = first; i <= last; ++i)
buffer[i - first] = ibuffer[i - first] * scale;
}
heap_free(ibuffer);
return ret;
}
/***********************************************************************
* *

View File

@ -7189,6 +7189,51 @@ static void test_GetCharWidthInfo(void)
ReleaseDC(NULL, hdc);
}
static int CALLBACK get_char_width_proc(const LOGFONTA *lf,
const TEXTMETRICA *tm, DWORD type, LPARAM ctx)
{
HFONT font = CreateFontIndirectA(lf);
HDC dc = GetDC(NULL);
const char c = 'm';
ABCFLOAT abcf;
int i, i32;
BOOL ret;
float f;
ABC abc;
SelectObject(dc, font);
ret = GetCharWidthFloatA(dc, c, c, &f);
ok(ret, "%s: GetCharWidthFloat() failed\n", lf->lfFaceName);
ret = GetCharWidth32A(dc, c, c, &i32);
ok(ret, "%s: GetCharWidth32A() failed\n", lf->lfFaceName);
ret = GetCharWidthA(dc, c, c, &i);
ok(ret, "%s: GetCharWidthA() failed\n", lf->lfFaceName);
ok(i == i32, "%s: mismatched widths %d/%d\n", lf->lfFaceName, i, i32);
ok((float)i / 16.0f == f, "%s: mismatched widths %d/%.8e\n", lf->lfFaceName, i, f);
ret = GetCharABCWidthsFloatA(dc, c, c, &abcf);
ok(ret, "%s: GetCharABCWidths() failed\n", lf->lfFaceName);
if (GetCharABCWidthsA(dc, c, c, &abc))
ok((float)abc.abcB == abcf.abcfB, "%s: mismatched widths %d/%.8e\n",
lf->lfFaceName, abc.abcB, abcf.abcfB);
ReleaseDC(NULL, dc);
DeleteObject(font);
return 1;
}
static void test_char_width(void)
{
HDC dc = GetDC(NULL);
LOGFONTA lf = {0};
lf.lfCharSet = DEFAULT_CHARSET;
EnumFontFamiliesExA(dc, &lf, get_char_width_proc, 0, 0);
ReleaseDC(NULL, dc);
}
START_TEST(font)
{
static const char *test_names[] =
@ -7271,6 +7316,7 @@ START_TEST(font)
test_bitmap_font_glyph_index();
test_GetCharWidthI();
test_long_names();
test_char_width();
/* These tests should be last test until RemoveFontResource
* is properly implemented.