From: Huw Davies Subject: Re: [PATCH v2] gdi32: Limit GetGlyphOutlineW(uChar) to a WORD. Message-Id: <534CD707-D613-4D1F-B3F0-9B91384DC303@codeweavers.com> Date: Wed, 23 Sep 2020 09:41:19 +0100 In-Reply-To: <20200922123928.483926-1-ahiler@codeweavers.com> References: <20200922123928.483926-1-ahiler@codeweavers.com> On 22 Sep 2020, at 13:39, Arkadiusz Hiler wrote: > diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c > index e099bec5e81..0fa1722d621 100644 > --- a/dlls/gdi32/font.c > +++ b/dlls/gdi32/font.c > @@ -2905,6 +2905,8 @@ DWORD WINAPI GetGlyphOutlineW( HDC hdc, UINT uChar, UINT fuFormat, > dc = get_dc_ptr(hdc); > if(!dc) return GDI_ERROR; > > + uChar &= 0xFFFF; > + I think it's safe to assume that this shouldn't happen if GGO_GLYPH_INDEX is specified. > dev = GET_DC_PHYSDEV( dc, pGetGlyphOutline ); > ret = dev->funcs->pGetGlyphOutline( dev, uChar, fuFormat, lpgm, cbBuffer, lpBuffer, lpmat2 ); > release_dc_ptr( dc ); > diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c > index f5c8d4dac3b..6410778c0e0 100644 > --- a/dlls/gdi32/tests/font.c > +++ b/dlls/gdi32/tests/font.c > @@ -5800,6 +5800,58 @@ todo_wine > ReleaseDC(NULL, hdc); > } > > +static void test_GetGlyphOutlineW_character_limited_to_a_word(void) > +{ > + HFONT hfont, hfont_old; > + LOGFONTA lf; > + HDC hdc; > + DWORD ret; > + GLYPHMETRICS gm1, gm2, gmn; > + char test_chars[] = { 'A', 'D', '!', '\0' }; > + > + memset(&lf, 0, sizeof(lf)); > + lf.lfHeight = 72; > + lstrcpyA(lf.lfFaceName, "wine_test"); > + > + hfont = CreateFontIndirectA(&lf); > + ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError()); > + > + hdc = GetDC(NULL); > + > + hfont_old = SelectObject(hdc, hfont); > + ok(hfont_old != NULL, "SelectObject failed\n"); > + > + ret = GetGlyphOutlineW(hdc, 'Z', GGO_METRICS, &gmn, 0, NULL, &mat); /* .notdef */ > + ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError()); > + > + for (char *current_char = test_chars; *current_char != '\0'; current_char++) > + { > + ret = GetGlyphOutlineW(hdc, *current_char, GGO_METRICS, &gm1, 0, NULL, &mat); > + ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError()); > + > + /* make sure we differ from .notdef */ > + ok(memcmp(&gm1, &gmn, sizeof(gmn)) != 0, "one of the test characters matches .notdef\n"); > + > + for (UINT offset = 0x10000; offset < 0xF0FF0000; offset += 0x1000000) Just testing with offset = 0x10000 will be fine. > + { > + ret = GetGlyphOutlineW(hdc, offset + *current_char, GGO_METRICS, &gm2, 0, NULL, &mat); > + ok(ret != GDI_ERROR, "GetGlyphOutlineW failed with %d, lest error %d\n", ret, GetLastError()); > + > + ok(gm1.gmBlackBoxX == gm2.gmBlackBoxX, "gmBlackBoxX differs, %d should equal %d\n", gm1.gmBlackBoxX, gm2.gmBlackBoxX); > + ok(gm1.gmBlackBoxY == gm2.gmBlackBoxY, "gmBlackBoxY differs, %d should equal %d\n", gm1.gmBlackBoxY, gm2.gmBlackBoxY); > + ok(gm1.gmptGlyphOrigin.x == gm2.gmptGlyphOrigin.x, "gmptGlyphOrigin.x differs, %d should equal %d\n", gm1.gmptGlyphOrigin.x, gm2.gmptGlyphOrigin.x); > + ok(gm1.gmptGlyphOrigin.y == gm2.gmptGlyphOrigin.y, "gmptGlyphOrigin.y difference, %d should equal %d\n", gm1.gmptGlyphOrigin.y, gm2.gmptGlyphOrigin.y); > + ok(gm1.gmCellIncX == gm2.gmCellIncX, "gmCellIncX differs, %d should equal %d\n", gm1.gmCellIncX, gm2.gmCellIncX); > + ok(gm1.gmCellIncY == gm2.gmCellIncY, "gmCellIncY differs, %d should equal %d\n", gm1.gmCellIncY, gm2.gmCellIncY); > + } > + } > + > + SelectObject(hdc, hfont_old); > + DeleteObject(hfont); > + > + DeleteDC(hdc); ReleaseDC() Huw.