Author: akhaldi Date: Sat Mar 16 15:01:33 2013 New Revision: 58518
URL: http://svn.reactos.org/svn/reactos?rev=58518&view=rev Log: [GDI32_WINETEST] * Sync with Wine 1.5.26.
Modified: trunk/rostests/winetests/gdi32/CMakeLists.txt trunk/rostests/winetests/gdi32/bitmap.c trunk/rostests/winetests/gdi32/clipping.c trunk/rostests/winetests/gdi32/dc.c trunk/rostests/winetests/gdi32/dib.c trunk/rostests/winetests/gdi32/font.c trunk/rostests/winetests/gdi32/gdiobj.c trunk/rostests/winetests/gdi32/metafile.c trunk/rostests/winetests/gdi32/wine_test.sfd trunk/rostests/winetests/gdi32/wine_test.ttf
Modified: trunk/rostests/winetests/gdi32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/CMakeLists... ============================================================================== --- trunk/rostests/winetests/gdi32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/CMakeLists.txt [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -1,7 +1,7 @@
add_definitions( -D__ROS_LONG64__ - -D_DLL -D__USE_CRTIMP) + -D__WINESRC__)
remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502)
@@ -22,9 +22,7 @@ pen.c testlist.c)
-add_executable(gdi32_winetest - ${SOURCE} - resource.rc) +add_executable(gdi32_winetest ${SOURCE} resource.rc)
if(NOT MSVC) # FIXME: http://www.cmake.org/Bug/view.php?id=12998
Modified: trunk/rostests/winetests/gdi32/bitmap.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/bitmap.c?r... ============================================================================== --- trunk/rostests/winetests/gdi32/bitmap.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/bitmap.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -339,16 +339,18 @@ ok(ret == 0, "%d != 0\n", ret); }
-#define test_color(hdc, color, exp) \ -{ \ - COLORREF c; \ - c = SetPixel(hdc, 0, 0, color); \ - ok(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \ - c = GetPixel(hdc, 0, 0); \ - ok(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \ - c = GetNearestColor(hdc, color); \ - ok(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, (UINT)exp); \ +static void _test_color( int line, HDC hdc, COLORREF color, COLORREF exp ) +{ + COLORREF c; + c = SetPixel(hdc, 0, 0, color); + ok_(__FILE__, line)(c == exp, "SetPixel failed: got 0x%06x expected 0x%06x\n", c, exp); + c = GetPixel(hdc, 0, 0); + ok_(__FILE__, line)(c == exp, "GetPixel failed: got 0x%06x expected 0x%06x\n", c, exp); + c = GetNearestColor(hdc, color); + ok_(__FILE__, line)(c == exp, "GetNearestColor failed: got 0x%06x expected 0x%06x\n", c, exp); } +#define test_color(hdc, color, exp) _test_color( __LINE__, hdc, color, exp ) +
static void test_dib_bits_access( HBITMAP hdib, void *bits ) { @@ -892,7 +894,7 @@
memset( data, 0xaa, sizeof(data) );
-#if 0 // FIXME: ReactOS Bug 6527 +#if 0 // FIXME: CORE-5922 for (bpp = 0; bpp <= 64; bpp++) { for (planes = 0; planes <= 64; planes++) @@ -1514,6 +1516,189 @@
DeleteObject(hbmp); DeleteDC(hdc); +} + +static COLORREF get_nearest( int r, int g, int b ) +{ + return (r*r + g*g + b*b < (255-r)*(255-r) + (255-g)*(255-g) + (255-b)*(255-b)) ? 0x000000 : 0xffffff; +} + +static int is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b ) +{ + if (fg == 0 || bg == 0xffffff) return RGB(r,g,b) != 0xffffff && RGB(r,g,b) != bg; + return RGB(r,g,b) == 0x000000 || RGB(r,g,b) == bg; +} + +static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g, int b ) +{ + static const WORD pattern_bits[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa }; + BITMAPINFO *info; + RGBQUAD *colors; + WORD bits[16]; + void *bits_ptr; + COLORREF res; + HBRUSH old_brush; + HPEN old_pen; + HBITMAP bitmap; + HDC memdc; + + res = SetPixel( hdc, 0, 0, RGB(r,g,b) ); + ok( res == get_nearest( r, g, b ), + "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); + res = GetPixel( hdc, 0, 0 ); + ok( res == get_nearest( r, g, b ), + "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); + res = GetNearestColor( hdc, RGB(r,g,b) ); + ok( res == get_nearest( r, g, b ), + "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); + + /* solid pen */ + old_pen = SelectObject( hdc, CreatePen( PS_SOLID, 1, RGB(r,g,b) )); + MoveToEx( hdc, 0, 0, NULL ); + LineTo( hdc, 16, 0 ); + res = GetPixel( hdc, 0, 0 ); + ok( res == (is_black_pen( fg, bg, r, g, b ) ? 0 : 0xffffff), + "wrong result %06x for %02x,%02x,%02x fg %06x bg %06x\n", res, r, g, b, fg, bg ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == (is_black_pen( fg, bg, r, g, b ) ? 0x00 : 0xffff), + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + DeleteObject( SelectObject( hdc, old_pen )); + + /* mono DDB pattern brush */ + bitmap = CreateBitmap( 16, 8, 1, 1, pattern_bits ); + old_brush = SelectObject( hdc, CreatePatternBrush( bitmap )); + PatBlt( hdc, 0, 0, 16, 16, PATCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0x5555, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + DeleteObject( SelectObject( hdc, old_brush )); + + /* mono DDB bitmap */ + memdc = CreateCompatibleDC( hdc ); + SelectObject( memdc, bitmap ); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0x5555, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + SetTextColor( memdc, RGB(255,255,255) ); + SetBkColor( memdc, RGB(0,0,0) ); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0x5555, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + + /* mono DIB section */ + info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET( BITMAPINFO, bmiColors[256] ) ); + colors = info->bmiColors; + info->bmiHeader.biSize = sizeof(info->bmiHeader); + info->bmiHeader.biHeight = -16; + info->bmiHeader.biWidth = 16; + info->bmiHeader.biBitCount = 1; + info->bmiHeader.biPlanes = 1; + info->bmiHeader.biCompression = BI_RGB; + colors[0].rgbRed = 0xff; + colors[0].rgbGreen = 0xff; + colors[0].rgbBlue = 0xf0; + colors[1].rgbRed = 0x20; + colors[1].rgbGreen = 0x0; + colors[1].rgbBlue = 0x0; + bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 ); + memset( bits_ptr, 0x55, 64 ); + DeleteObject( SelectObject( memdc, bitmap )); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0x5555, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + + colors[0].rgbRed = 0x0; + colors[0].rgbGreen = 0x0; + colors[0].rgbBlue = 0x10; + colors[1].rgbRed = 0xff; + colors[1].rgbGreen = 0xf0; + colors[1].rgbBlue = 0xff; + bitmap = CreateDIBSection( 0, info, DIB_RGB_COLORS, &bits_ptr, NULL, 0 ); + memset( bits_ptr, 0x55, 64 ); + DeleteObject( SelectObject( memdc, bitmap )); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0xaaaa, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + + SetTextColor( memdc, RGB(0,20,0) ); + SetBkColor( memdc, RGB(240,240,240) ); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0x5555, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + + SetTextColor( memdc, RGB(250,250,250) ); + SetBkColor( memdc, RGB(10,10,10) ); + BitBlt( hdc, 0, 0, 16, 8, memdc, 0, 0, SRCCOPY ); + GetBitmapBits( GetCurrentObject( hdc, OBJ_BITMAP ), sizeof(bits), bits ); + ok( bits[0] == 0xaaaa, + "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg ); + DeleteDC( memdc ); + DeleteObject( bitmap ); + HeapFree( GetProcessHeap(), 0, info ); +} + +static void test_mono_bitmap(void) +{ + static const COLORREF colors[][2] = + { + { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xff) }, + { RGB(0xff,0xff,0xff), RGB(0x00,0x00,0x00) }, + { RGB(0x00,0x00,0x00), RGB(0xff,0xff,0xfe) }, + { RGB(0x00,0x01,0x00), RGB(0xff,0xff,0xff) }, + { RGB(0x00,0x00,0x00), RGB(0x80,0x80,0x80) }, + { RGB(0x80,0x80,0x80), RGB(0xff,0xff,0xff) }, + { RGB(0x30,0x40,0x50), RGB(0x60,0x70,0x80) }, + { RGB(0xa0,0xa0,0xa0), RGB(0x20,0x30,0x10) }, + { PALETTEINDEX(0), PALETTEINDEX(255) }, + { PALETTEINDEX(1), PALETTEINDEX(2) }, + }; + + HBITMAP hbmp; + HDC hdc; + DWORD col; + int i, r, g, b; + + if (!winetest_interactive) + { + skip("test_mono_bitmap skipped, CORE-5922\n"); + return; + } + + hdc = CreateCompatibleDC(0); + assert(hdc != 0); + + hbmp = CreateBitmap(16, 16, 1, 1, NULL); + assert(hbmp != NULL); + + SelectObject( hdc, hbmp ); + + for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++) + { + SetTextColor( hdc, colors[col][0] ); + SetBkColor( hdc, colors[col][1] ); + + for (i = 0; i < 256; i++) + { + HPALETTE pal = GetCurrentObject( hdc, OBJ_PAL ); + PALETTEENTRY ent; + + if (!GetPaletteEntries( pal, i, 1, &ent )) GetPaletteEntries( pal, 0, 1, &ent ); + test_color( hdc, PALETTEINDEX(i), get_nearest( ent.peRed, ent.peGreen, ent.peBlue )); + test_color( hdc, DIBINDEX(i), (i == 1) ? 0xffffff : 0x000000 ); + } + for (r = 0; r < 256; r += 15) + for (g = 0; g < 256; g += 15) + for (b = 0; b < 256; b += 15) + test_bitmap_colors( hdc, colors[col][0], colors[col][1], r, g, b ); + } + + DeleteDC(hdc); + DeleteObject(hbmp); }
static void test_bmBits(void) @@ -3176,12 +3361,13 @@ dwRop, expected, *dstBuffer, line); }
-static void check_StretchDIBits_stretch(HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer, +static INT check_StretchDIBits_stretch( HDC hdcDst, UINT32 *dstBuffer, UINT32 *srcBuffer, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, UINT32 expected[4], int line) { BITMAPINFO bitmapInfo; + INT ret;
memset(&bitmapInfo, 0, sizeof(BITMAPINFO)); bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -3192,9 +3378,9 @@ bitmapInfo.bmiHeader.biCompression = BI_RGB;
memset(dstBuffer, 0, 16); - StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, - nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, - srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); + ret = StretchDIBits(hdcDst, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, + nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, + srcBuffer, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); ok(memcmp(dstBuffer, expected, 16) == 0, "StretchDIBits expected { %08X, %08X, %08X, %08X } got { %08X, %08X, %08X, %08X } " "stretching { %d, %d, %d, %d } to { %d, %d, %d, %d } from line %d\n", @@ -3202,6 +3388,7 @@ dstBuffer[0], dstBuffer[1], dstBuffer[2], dstBuffer[3], nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, line); + return ret; }
static void test_StretchDIBits(void) @@ -3213,6 +3400,7 @@ HBRUSH hBrush, hOldBrush; BITMAPINFO biDst; UINT32 expected[4]; + INT ret;
memset(&biDst, 0, sizeof(BITMAPINFO)); biDst.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -3258,43 +3446,63 @@
expected[0] = 0xCAFED00D, expected[1] = 0xFEEDFACE; expected[2] = 0xFEDCBA98, expected[3] = 0x76543210; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 2, 2, 0, 0, 2, 2, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret );
expected[0] = 0xCAFED00D, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0x00000000; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 1, 1, 0, 0, 1, 1, expected, __LINE__); + todo_wine ok( ret == 1, "got ret %d\n", ret );
expected[0] = 0xFEDCBA98, expected[1] = 0xFEDCBA98; expected[2] = 0xFEDCBA98, expected[3] = 0xFEDCBA98; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 2, 2, 0, 0, 1, 1, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret );
expected[0] = 0x42441000, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0x00000000; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 1, 1, 0, 0, 2, 2, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret );
expected[0] = 0x00000000, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0x00000000; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); + ok( ret == 0, "got ret %d\n", ret );
expected[0] = 0x00000000, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0x00000000; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 0, 0, 2, 2, 1, 1, -2, -2, expected, __LINE__); + ok( ret == 0, "got ret %d\n", ret );
expected[0] = 0x00000000, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0x00000000; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 1, 1, -2, -2, 1, 1, -2, -2, expected, __LINE__); + ok( ret == 0, "got ret %d\n", ret );
expected[0] = 0x00000000, expected[1] = 0x00000000; expected[2] = 0x00000000, expected[3] = 0xCAFED00D; - check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, - 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__); + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 1, 1, 2, 2, 0, 0, 2, 2, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret ); + + expected[0] = 0x00000000, expected[1] = 0x00000000; + expected[2] = 0x00000000, expected[3] = 0x00000000; + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + 2, 2, 4, 4, 0, 0, 2, 2, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret ); + + expected[0] = 0x00000000, expected[1] = 0x00000000; + expected[2] = 0x00000000, expected[3] = 0x00000000; + ret = check_StretchDIBits_stretch(hdcDst, dstBuffer, srcBuffer, + -4, -4, 4, 4, 0, 0, 4, 4, expected, __LINE__); + ok( ret == 2, "got ret %d\n", ret );
SelectObject(hdcDst, oldDst); DeleteObject(bmpDst); @@ -3323,7 +3531,6 @@ HDC hdcNull; HDC hdcDst; HBITMAP bmpDst; - HBITMAP oldDst; BITMAPINFO *bmi; HDC hdcSrc; HBITMAP bmpSrc; @@ -3353,7 +3560,7 @@ bmpSrc = CreateDIBSection(hdcDst, bmi, DIB_RGB_COLORS, &bits, NULL, 0); ok(bmpSrc != NULL, "Couldn't create source bitmap\n");
- oldDst = SelectObject(hdcDst, bmpDst); + SelectObject(hdcDst, bmpDst); oldSrc = SelectObject(hdcSrc, bmpSrc);
blend.BlendOp = AC_SRC_OVER; @@ -3399,6 +3606,7 @@ SetViewportExtEx(hdcDst, -1, -1, NULL); SetLastError(0xdeadbeef); ret = pGdiAlphaBlend(hdcDst, 0, 0, 20, 20, hdcSrc, 0, -1, 50, 50, blend); + todo_wine ok( ret, "GdiAlphaBlend failed err %u\n", GetLastError() ); SetLastError(0xdeadbeef); ret = pGdiAlphaBlend(hdcDst, -20, -20, 20, 20, hdcSrc, 0, -1, 50, 50, blend); @@ -3535,15 +3743,13 @@ ok( !ret, "GdiAlphaBlend succeeded\n" ); ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
- SelectObject(hdcDst, oldDst); - SelectObject(hdcSrc, oldSrc); + DeleteDC(hdcDst); + DeleteDC(hdcSrc); DeleteObject(bmpSrc); DeleteObject(bmpDst); - DeleteDC(hdcDst); - DeleteDC(hdcSrc);
ReleaseDC(NULL, hdcNull); - + HeapFree(GetProcessHeap(), 0, bmi); }
static void test_GdiGradientFill(void) @@ -3656,6 +3862,7 @@
DeleteDC( hdc ); DeleteObject( bmp ); + HeapFree(GetProcessHeap(), 0, bmi); }
static void test_clipping(void) @@ -5388,6 +5595,7 @@ test_dib_formats(); test_mono_dibsection(); test_bitmap(); + test_mono_bitmap(); test_bmBits(); test_GetDIBits_selected_DIB(1); test_GetDIBits_selected_DIB(4);
Modified: trunk/rostests/winetests/gdi32/clipping.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/clipping.c... ============================================================================== --- trunk/rostests/winetests/gdi32/clipping.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/clipping.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -401,6 +401,14 @@ ok(rc.left == 0 && rc.top == 0 && rc.right == 100 && rc.bottom == 100, "expected 0,0-100,100, got %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom);
+ SetRect( &rc, 10, 10, 20, 20 ); + ret = RectVisible( hdc, &rc ); + ok( ret, "RectVisible failed for %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom ); + + SetRect( &rc, 20, 20, 10, 10 ); + ret = RectVisible( hdc, &rc ); + ok( ret, "RectVisible failed for %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom ); + DeleteDC(hdc); DeleteObject(hrgn); DeleteObject(hrgn_empty); @@ -446,6 +454,14 @@ "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width, screen_height, rc.left, rc.top, rc.right, rc.bottom);
+ SetRect( &rc, 10, 10, 20, 20 ); + ret = RectVisible( hdc, &rc ); + ok( ret, "RectVisible failed for %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom ); + + SetRect( &rc, 20, 20, 10, 10 ); + ret = RectVisible( hdc, &rc ); + ok( ret, "RectVisible failed for %d,%d-%d,%d\n", rc.left, rc.top, rc.right, rc.bottom ); + ret = ExtSelectClipRgn(hdc, 0, RGN_COPY); ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1), "expected SIMPLEREGION, got %d\n", ret);
Modified: trunk/rostests/winetests/gdi32/dc.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/dc.c?rev=5... ============================================================================== --- trunk/rostests/winetests/gdi32/dc.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/dc.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -19,7 +19,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+ #define WINVER 0x0501 /* request latest DEVMODE */ +#define NONAMELESSSTRUCT +#define NONAMELESSUNION
#include <assert.h> #include <stdio.h> @@ -30,6 +33,10 @@ #include "winuser.h" #include "winspool.h" #include "winerror.h" + +#ifndef LAYOUT_LTR +#define LAYOUT_LTR 0 +#endif
static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
@@ -58,6 +65,7 @@ { HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); COLORREF color; + int extra;
ok( hdc != NULL, "CreateDC failed\n" ); color = SetBkColor( hdc, 0x12345678 ); @@ -86,6 +94,18 @@ color = GetTextColor( hdc ); ok( color == 0, "wrong color %08x\n", color );
+ extra = GetTextCharacterExtra( hdc ); + ok( extra == 0, "initial extra %d\n", extra ); + SetTextCharacterExtra( hdc, 123 ); + extra = GetTextCharacterExtra( hdc ); + ok( extra == 123, "initial extra %d\n", extra ); + SetMapMode( hdc, MM_LOMETRIC ); + extra = GetTextCharacterExtra( hdc ); + ok( extra == 123, "initial extra %d\n", extra ); + SetMapMode( hdc, MM_TEXT ); + extra = GetTextCharacterExtra( hdc ); + ok( extra == 123, "initial extra %d\n", extra ); + DeleteDC( hdc ); }
@@ -124,10 +144,7 @@ rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
ret = SaveDC(hdc); -todo_wine -{ ok(ret == 1, "ret = %d\n", ret); -}
ret = IntersectClipRect(hdc, 0, 0, 50, 50); if (ret == COMPLEXREGION) @@ -298,7 +315,7 @@ HeapFree(GetProcessHeap(), 0, dmW); }
-static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr ) +static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale ) { static const int caps[] = { @@ -374,27 +391,59 @@ else { for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++) - ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ), - "mismatched caps on %s for %u: %u/%u\n", descr, caps[i], - GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) ); + { + INT precision = 0; + INT hdc_caps = GetDeviceCaps( hdc, caps[i] ); + + switch (caps[i]) + { + case HORZSIZE: + case VERTSIZE: + hdc_caps /= scale; + precision = 1; + break; + case LOGPIXELSX: + case LOGPIXELSY: + hdc_caps *= scale; + break; + } + + ok( abs(hdc_caps - GetDeviceCaps( ref_dc, caps[i] )) <= precision, + "mismatched caps on %s for %u: %u/%u (scale %d)\n", descr, caps[i], + hdc_caps, GetDeviceCaps( ref_dc, caps[i] ), scale ); + }
SetLastError( 0xdeadbeef ); ret = GetDeviceGammaRamp( hdc, &ramp ); - ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr ); - ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */ - "wrong error %u on %s\n", GetLastError(), descr ); + if (GetObjectType( hdc ) != OBJ_DC || GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER) + { + ok( !ret, "GetDeviceGammaRamp succeeded on %s (type %d)\n", descr, GetObjectType( hdc ) ); + ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */ + "wrong error %u on %s\n", GetLastError(), descr ); + } + else + ok( ret || broken(!ret) /* NT4 */, "GetDeviceGammaRamp failed on %s (type %d), error %u\n", descr, GetObjectType( hdc ), GetLastError() ); type = GetClipBox( hdc, &rect ); if (GetObjectType( hdc ) == OBJ_ENHMETADC) todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr ); else ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
+ type = GetBoundsRect( hdc, &rect, 0 ); + ok( type == DCB_RESET || broken(type == DCB_SET) /* XP */, + "GetBoundsRect returned type %x for %s\n", type, descr ); + if (type == DCB_RESET) + ok( rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0, + "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n", + rect.left, rect.top, rect.right, rect.bottom, type, descr ); type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE ); - ok( type == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", type ); + ok( type == (DCB_RESET | DCB_DISABLE) || broken(type == (DCB_SET | DCB_ENABLE)) /* XP */, + "SetBoundsRect returned %x for %s (hdc type %d)\n", type, descr, GetObjectType( hdc ) ); + SetMapMode( hdc, MM_TEXT ); Rectangle( hdc, 2, 2, 4, 4 ); type = GetBoundsRect( hdc, &rect, DCB_RESET ); - if (GetObjectType( hdc ) == OBJ_ENHMETADC) + if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER)) todo_wine ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET, "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n", @@ -406,7 +455,7 @@ }
type = GetClipBox( ref_dc, &rect ); - if (type != COMPLEXREGION) /* region can be complex on multi-monitor setups */ + if (type != COMPLEXREGION && type != ERROR) /* region can be complex on multi-monitor setups */ { ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr ); ok( rect.left == 0 && rect.top == 0 && @@ -470,6 +519,10 @@ SelectObject( hdc, old ); DeleteObject( dib ); } + + /* restore hdc state */ + SetBoundsRect( hdc, NULL, DCB_RESET | DCB_DISABLE ); + SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_DISABLE ); }
static void test_CreateCompatibleDC(void) @@ -478,9 +531,21 @@ HDC hdc, hNewDC, hdcMetafile, screen_dc; HBITMAP bitmap; INT caps; + DEVMODE dm; + + bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); + + bRet = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm); + ok(bRet, "EnumDisplaySettingsEx failed\n"); + dm.u1.s1.dmScale = 200; + dm.dmFields |= DM_SCALE; + hdc = CreateDC( "DISPLAY", NULL, NULL, &dm );
screen_dc = CreateDC( "DISPLAY", NULL, NULL, NULL ); - bitmap = CreateBitmap( 10, 10, 1, 1, NULL ); + test_device_caps( hdc, screen_dc, "display dc", 1 ); + ResetDC( hdc, &dm ); + test_device_caps( hdc, screen_dc, "display dc", 1 ); + DeleteDC( hdc );
/* Create a DC compatible with the screen */ hdc = CreateCompatibleDC(NULL); @@ -489,7 +554,7 @@ caps = GetDeviceCaps( hdc, TECHNOLOGY ); ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
- test_device_caps( hdc, screen_dc, "display dc" ); + test_device_caps( hdc, screen_dc, "display dc", 1 );
/* Delete this DC, this should succeed */ bRet = DeleteDC(hdc); @@ -507,7 +572,9 @@ ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" ); caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY ); ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps ); - test_device_caps( hdcMetafile, hdc, "enhmetafile dc" ); + test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 ); + ResetDC( hdcMetafile, &dm ); + test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 ); DeleteDC( hNewDC ); DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile )); ReleaseDC( 0, hdc ); @@ -518,7 +585,9 @@ ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n"); caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY ); ok( caps == DT_METAFILE, "wrong caps %u\n", caps ); - test_device_caps( hdcMetafile, screen_dc, "metafile dc" ); + test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 ); + ResetDC( hdcMetafile, &dm ); + test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 ); DeleteMetaFile( CloseMetaFile( hdcMetafile ));
DeleteObject( bitmap ); @@ -1139,7 +1208,17 @@ ReleaseDC(NULL, hdc); }
-static HDC create_printer_dc(void) +static BOOL is_postscript_printer(HDC hdc) +{ + char tech[256]; + + if (ExtEscape(hdc, GETTECHNOLOGY, 0, NULL, sizeof(tech), tech) > 0) + return strcmp(tech, "PostScript") == 0; + + return FALSE; +} + +static HDC create_printer_dc(int scale, BOOL reset) { char buffer[260]; DWORD len; @@ -1175,9 +1254,15 @@ dbuf = HeapAlloc( GetProcessHeap(), 0, len ); if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
+ pbuf->pDevMode->u1.s1.dmScale = scale; + pbuf->pDevMode->dmFields |= DM_SCALE; + hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode ); - trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc, - dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName ); + trace( "hdc %p for driver '%s' printer '%s' port '%s' is %sPostScript\n", hdc, + dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, + is_postscript_printer(hdc) ? "" : "NOT " ); + + if (reset) ResetDC( hdc, pbuf->pDevMode ); done: HeapFree( GetProcessHeap(), 0, dbuf ); HeapFree( GetProcessHeap(), 0, pbuf ); @@ -1192,9 +1277,19 @@ HDC memdc, display_memdc, enhmf_dc; HBITMAP orig, bmp; DWORD ret; - HDC hdc = create_printer_dc(); - - if (!hdc) return; + HDC hdc, hdc_200; + + hdc = create_printer_dc(100, FALSE); + hdc_200 = create_printer_dc(200, FALSE); + + if (!hdc || !hdc_200) return; + + test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 ); + DeleteDC( hdc_200 ); + + hdc_200 = create_printer_dc(200, TRUE); + test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 ); + DeleteDC( hdc_200 );
memdc = CreateCompatibleDC( hdc ); display_memdc = CreateCompatibleDC( 0 ); @@ -1216,7 +1311,7 @@ ok( orig != NULL, "SelectObject failed\n" ); ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
- test_device_caps( memdc, hdc, "printer dc" ); + test_device_caps( memdc, hdc, "printer dc", 1 );
ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" ); SelectObject( memdc, orig ); @@ -1235,7 +1330,12 @@
enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL ); ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n"); - test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc" ); + test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 ); + DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc )); + + enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL ); + ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n"); + test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 ); DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
DeleteDC( memdc );
Modified: trunk/rostests/winetests/gdi32/dib.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/dib.c?rev=... ============================================================================== --- trunk/rostests/winetests/gdi32/dib.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/dib.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -1312,6 +1312,7 @@ if(current_sha1[i] == NULL) { ok(current_sha1[i] != NULL, "missing hash, got "%s",\n", hash); + HeapFree(GetProcessHeap(), 0, hash); return; } } @@ -1908,6 +1909,7 @@
DeleteObject(bmp); SelectObject(hdc, orig_brush); + DeleteObject( dib_brush ); SetBrushOrgEx(hdc, 0, 0, NULL); SetTextColor(hdc, old_text); SetBkColor(hdc, old_bkgnd); @@ -2660,7 +2662,6 @@
SelectObject(hdc, orig_brush); SelectObject(hdc, orig_pen); - DeleteObject(dib_brush); DeleteObject(solid_brush); DeleteObject(wide_pen); DeleteObject(dashed_pen);
Modified: trunk/rostests/winetests/gdi32/font.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/font.c?rev... ============================================================================== --- trunk/rostests/winetests/gdi32/font.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/font.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -45,6 +45,8 @@ static DWORD (WINAPI *pGetFontUnicodeRanges)(HDC hdc, LPGLYPHSET lpgs); static DWORD (WINAPI *pGetGlyphIndicesA)(HDC hdc, LPCSTR lpstr, INT count, LPWORD pgi, DWORD flags); static DWORD (WINAPI *pGetGlyphIndicesW)(HDC hdc, LPCWSTR lpstr, INT count, LPWORD pgi, DWORD flags); +static BOOL (WINAPI *pGetTextExtentExPointI)(HDC hdc, const WORD *indices, INT count, INT max_ext, + LPINT nfit, LPINT dxs, LPSIZE size ); static BOOL (WINAPI *pGdiRealizationInfo)(HDC hdc, DWORD *); static HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDV *); static HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *); @@ -54,6 +56,7 @@
static HMODULE hgdi32 = 0; static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} }; +static WORD system_lang_id;
static void init(void) { @@ -68,12 +71,15 @@ pGetFontUnicodeRanges = (void *)GetProcAddress(hgdi32, "GetFontUnicodeRanges"); pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA"); pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW"); + pGetTextExtentExPointI = (void *)GetProcAddress(hgdi32, "GetTextExtentExPointI"); pGdiRealizationInfo = (void *)GetProcAddress(hgdi32, "GdiRealizationInfo"); pCreateFontIndirectExA = (void *)GetProcAddress(hgdi32, "CreateFontIndirectExA"); pAddFontMemResourceEx = (void *)GetProcAddress(hgdi32, "AddFontMemResourceEx"); pRemoveFontMemResourceEx = (void *)GetProcAddress(hgdi32, "RemoveFontMemResourceEx"); pAddFontResourceExA = (void *)GetProcAddress(hgdi32, "AddFontResourceExA"); pRemoveFontResourceExA = (void *)GetProcAddress(hgdi32, "RemoveFontResourceExA"); + + system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID()); }
static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) @@ -680,6 +686,11 @@ return 1; /* continue enumeration */ }
+static BOOL is_CJK(void) +{ + return (system_lang_id == LANG_CHINESE || system_lang_id == LANG_JAPANESE || system_lang_id == LANG_KOREAN); +} + #define FH_SCALE 0x80000000 static void test_bitmap_font_metrics(void) { @@ -694,15 +705,15 @@ int scaled_height; } fd[] = { - { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 13 }, + { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC, 13 }, { "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 }, - { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 13 }, + { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC, 13 }, { "MS Sans Serif", FW_NORMAL, FH_SCALE | 8, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 }, - { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 13 }, + { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC, 13 }, { "MS Sans Serif", FW_NORMAL, FH_SCALE | 10, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 }, - { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 13 }, + { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC, 13 }, { "MS Sans Serif", FW_NORMAL, FH_SCALE | 14, 11, 2, 2, 0, 5, 11, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 13 }, - { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 }, + { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC, 16 }, { "MS Sans Serif", FW_NORMAL, FH_SCALE | 18, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x7f, 0x20, FS_CYRILLIC, 0, 16 },
{ "MS Sans Serif", FW_NORMAL, FH_SCALE | 6, 13, 3, 3, 0, 7, 14, 120, 0x20, 0xff, 0x81, 0x20, FS_LATIN1 | FS_LATIN2, 0, 16 }, @@ -786,32 +797,32 @@
{ "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 14, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 }, { "System", FW_BOLD, 16, 13, 3, 3, 0, 7, 15, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, - { "System", FW_NORMAL, 18, 16, 2, 0, 2, 8, 16, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "System", FW_NORMAL, 18, 16, 2, 0, 2, 8, 16, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
{ "System", FW_BOLD, 20, 16, 4, 4, 0, 9, 14, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 }, { "System", FW_BOLD, 20, 16, 4, 4, 0, 9, 17, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC },
{ "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 2, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 }, { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, - { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 2, 4, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 2, 4, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 5, 4, 1, 1, 0, 3, 4, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, LANG_ARABIC }, { "Small Fonts", FW_NORMAL, 5, 4, 1, 1, 0, 2, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, - { "Small Fonts", FW_NORMAL, 5, 4, 1, 0, 0, 3, 6, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 5, 4, 1, 0, 0, 3, 6, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 13, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, LANG_ARABIC }, { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, - { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 96, 0, 0, 0, 0, FS_ARABIC }, - { "Small Fonts", FW_NORMAL, 6, 5, 1, 0, 0, 4, 8, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 6, 5, 1, 1, 0, 3, 8, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC }, + { "Small Fonts", FW_NORMAL, 6, 5, 1, 0, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 7, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1, LANG_ARABIC }, { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, - { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 96, 0, 0, 0, 0, FS_ARABIC }, - { "Small Fonts", FW_NORMAL, 8, 7, 1, 0, 0, 5, 10, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 8, 7, 1, 1, 0, 4, 8, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC }, + { "Small Fonts", FW_NORMAL, 8, 7, 1, 0, 0, 5, 10, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2, LANG_ARABIC }, { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 5, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC }, - { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 9, 96, 0, 0, 0, 0, FS_ARABIC }, - { "Small Fonts", FW_NORMAL, 10, 8, 2, 0, 0, 6, 12, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 10, 8, 2, 2, 0, 4, 9, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC }, + { "Small Fonts", FW_NORMAL, 10, 8, 2, 0, 0, 6, 12, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 5, 9, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC, LANG_ARABIC }, - { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 4, 10, 96, 0, 0, 0, 0, FS_ARABIC }, - { "Small Fonts", FW_NORMAL, 11, 9, 2, 0, 0, 7, 14, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "Small Fonts", FW_NORMAL, 11, 9, 2, 2, 0, 4, 10, 96, 0x00, 0xff, 0x60, 0x00, FS_ARABIC }, + { "Small Fonts", FW_NORMAL, 11, 9, 2, 0, 0, 7, 14, 96, 0x20, 0xff, 0x80, 0x20, FS_JISJAPAN },
{ "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 2, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_JISJAPAN }, { "Small Fonts", FW_NORMAL, 3, 2, 1, 0, 0, 1, 8, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN2 | FS_CYRILLIC }, @@ -828,7 +839,7 @@
{ "Fixedsys", FW_NORMAL, 15, 12, 3, 3, 0, 8, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 }, { "Fixedsys", FW_NORMAL, 16, 12, 4, 3, 0, 8, 8, 96, 0x20, 0xff, 0x80, 0x20, FS_CYRILLIC }, - { "FixedSys", FW_NORMAL, 18, 16, 2, 0, 0, 8, 16, 96, 0, 0, 0, 0, FS_JISJAPAN }, + { "FixedSys", FW_NORMAL, 18, 16, 2, 0, 0, 8, 16, 96, 0x20, 0xff, 0xa0, 0x20, FS_JISJAPAN },
{ "Fixedsys", FW_NORMAL, 20, 16, 4, 2, 0, 10, 10, 120, 0x20, 0xff, 0x80, 0x20, FS_LATIN1 | FS_LATIN2 | FS_CYRILLIC }
@@ -840,11 +851,9 @@ HFONT hfont, old_hfont; TEXTMETRIC tm; INT ret, i, expected_cs, screen_log_pixels, diff, font_res; - WORD system_lang_id; char face_name[LF_FACESIZE]; CHARSETINFO csi;
- system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID()); trace("system language id %04x\n", system_lang_id);
expected_cs = GetACP(); @@ -888,6 +897,7 @@
for(bit = 0; bit < 32; bit++) { + GLYPHMETRICS gm; DWORD fs[2]; BOOL bRet;
@@ -916,15 +926,10 @@
hfont = create_font(lf.lfFaceName, &lf); old_hfont = SelectObject(hdc, hfont); - bRet = GetTextMetrics(hdc, &tm); - ok(bRet, "GetTextMetrics error %d\n", GetLastError());
SetLastError(0xdeadbeef); ret = GetTextFace(hdc, sizeof(face_name), face_name); ok(ret, "GetTextFace error %u\n", GetLastError()); - - SetLastError(0xdeadbeef); - ret = GetTextCharset(hdc);
if (lstrcmp(face_name, fd[i].face_name) != 0) { @@ -936,7 +941,23 @@ continue; }
- ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs); + memset(&gm, 0, sizeof(gm)); + SetLastError(0xdeadbeef); + ret = GetGlyphOutline(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat); + todo_wine { + ok(ret == GDI_ERROR, "GetGlyphOutline should fail for a bitmap font\n"); + ok(GetLastError() == ERROR_CAN_NOT_COMPLETE, "expected ERROR_CAN_NOT_COMPLETE, got %u\n", GetLastError()); + } + + bRet = GetTextMetrics(hdc, &tm); + ok(bRet, "GetTextMetrics error %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + ret = GetTextCharset(hdc); + if (is_CJK() && lf.lfCharSet == ANSI_CHARSET) + ok(ret == ANSI_CHARSET, "got charset %d, expected ANSI_CHARSETd\n", ret); + else + ok(ret == expected_cs, "got charset %d, expected %d\n", ret, expected_cs);
trace("created %s, height %d charset %x dpi %d\n", face_name, tm.tmHeight, tm.tmCharSet, tm.tmDigitizedAspectX); trace("expected %s, height %d scaled_hight %d, dpi %d\n", fd[i].face_name, height, fd[i].scaled_height, fd[i].dpi); @@ -1288,20 +1309,20 @@ fit1 = fit2 = -215; ret = GetTextExtentExPointA(hdc, "One", 3, -1, &fit1, NULL, &sz); ok(ret == TRUE, "got %d\n", ret); - todo_wine ok(fit1 == 3, "fit = %d\n", fit1); + ok(fit1 == 3, "fit = %d\n", fit1); ret = GetTextExtentExPointW(hdc, wt, 3, -1, &fit2, NULL, &sz); ok(ret == TRUE, "got %d\n", ret); - todo_wine ok(fit2 == 3, "fit = %d\n", fit2); + ok(fit2 == 3, "fit = %d\n", fit2);
/* max_extent = -2 is interpreted similarly, but the Ansi version * rejects it while the Unicode one accepts it */ fit1 = fit2 = -215; ret = GetTextExtentExPointA(hdc, "One", 3, -2, &fit1, NULL, &sz); - todo_wine ok(ret == FALSE, "got %d\n", ret); - todo_wine ok(fit1 == -215, "fit = %d\n", fit1); + ok(ret == FALSE, "got %d\n", ret); + ok(fit1 == -215, "fit = %d\n", fit1); ret = GetTextExtentExPointW(hdc, wt, 3, -2, &fit2, NULL, &sz); ok(ret == TRUE, "got %d\n", ret); - todo_wine ok(fit2 == 3, "fit = %d\n", fit2); + ok(fit2 == 3, "fit = %d\n", fit2);
hfont = SelectObject(hdc, hfont); DeleteObject(hfont); @@ -1747,18 +1768,17 @@ { INT y, breakCount, - justifiedWidth = 0, /* to test GetTextExtentExPointW() */ areaWidth = clientArea->right - clientArea->left, nErrors = 0, e; - BOOL lastExtent = FALSE; PSTR pFirstChar, pLastChar; SIZE size; TEXTMETRICA tm; struct err { - char extent[100]; + char *start; + int len; int GetTextExtentExPointWWidth; - } error[10]; + } error[20];
GetTextMetricsA(hdc, &tm); y = clientArea->top; @@ -1797,18 +1817,16 @@ { SetTextJustification(hdc, areaWidth - size.cx, breakCount); GetTextExtentPoint32(hdc, pFirstChar, pLastChar - pFirstChar, &size); - justifiedWidth = size.cx; + if (size.cx != areaWidth && nErrors < sizeof(error)/sizeof(error[0]) - 1) + { + error[nErrors].start = pFirstChar; + error[nErrors].len = pLastChar - pFirstChar; + error[nErrors].GetTextExtentExPointWWidth = size.cx; + nErrors++; + } } - else lastExtent = TRUE; - - /* catch errors and report them */ - if (!lastExtent && (justifiedWidth != areaWidth)) - { - memset(error[nErrors].extent, 0, 100); - memcpy(error[nErrors].extent, pFirstChar, pLastChar - pFirstChar); - error[nErrors].GetTextExtentExPointWWidth = justifiedWidth; - nErrors++; - } + + trace( "%u %.*s\n", size.cx, (int)(pLastChar - pFirstChar), pFirstChar);
y += size.cy; str = pLastChar; @@ -1819,8 +1837,8 @@ /* The width returned by GetTextExtentPoint32() is exactly the same returned by GetTextExtentExPointW() - see dlls/gdi32/font.c */ ok(error[e].GetTextExtentExPointWWidth == areaWidth, - "GetTextExtentPointW() for "%s" should have returned a width of %d, not %d.\n", - error[e].extent, areaWidth, error[e].GetTextExtentExPointWWidth); + "GetTextExtentPointW() for "%.*s" should have returned a width of %d, not %d.\n", + error[e].len, error[e].start, areaWidth, error[e].GetTextExtentExPointWWidth); } }
@@ -1831,6 +1849,9 @@ LOGFONTA lf; HFONT hfont; HWND hwnd; + SIZE size, expect; + int i; + WORD indices[2]; static char testText[] = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do " "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut " @@ -1856,6 +1877,74 @@
testJustification(hdc, testText, &clientArea);
+ if (!pGetGlyphIndicesA || !pGetTextExtentExPointI) goto done; + pGetGlyphIndicesA( hdc, "A ", 2, indices, 0 ); + + SetTextJustification(hdc, 0, 0); + GetTextExtentPoint32(hdc, " ", 1, &expect); + GetTextExtentPoint32(hdc, " ", 3, &size); + ok( size.cx == 3 * expect.cx, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 4, 1); + GetTextExtentPoint32(hdc, " ", 1, &size); + ok( size.cx == expect.cx + 4, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 9, 2); + GetTextExtentPoint32(hdc, " ", 2, &size); + ok( size.cx == 2 * expect.cx + 9, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 7, 3); + GetTextExtentPoint32(hdc, " ", 3, &size); + ok( size.cx == 3 * expect.cx + 7, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 7, 3); + SetTextCharacterExtra(hdc, 2 ); + GetTextExtentPoint32(hdc, " ", 3, &size); + ok( size.cx == 3 * (expect.cx + 2) + 7, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 0, 0); + SetTextCharacterExtra(hdc, 0); + size.cx = size.cy = 1234; + GetTextExtentPoint32(hdc, " ", 0, &size); + ok( size.cx == 0 && size.cy == 0, "wrong size %d,%d\n", size.cx, size.cy ); + pGetTextExtentExPointI(hdc, indices, 2, -1, NULL, NULL, &expect); + SetTextJustification(hdc, 5, 1); + pGetTextExtentExPointI(hdc, indices, 2, -1, NULL, NULL, &size); + ok( size.cx == expect.cx + 5, "wrong size %d/%d\n", size.cx, expect.cx ); + SetTextJustification(hdc, 0, 0); + + SetMapMode( hdc, MM_ANISOTROPIC ); + SetWindowExtEx( hdc, 2, 2, NULL ); + GetClientRect( hwnd, &clientArea ); + DPtoLP( hdc, (POINT *)&clientArea, 2 ); + testJustification(hdc, testText, &clientArea); + + GetTextExtentPoint32(hdc, "A", 1, &expect); + for (i = 0; i < 10; i++) + { + SetTextCharacterExtra(hdc, i); + GetTextExtentPoint32(hdc, "A", 1, &size); + ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i ); + } + SetTextCharacterExtra(hdc, 0); + pGetTextExtentExPointI(hdc, indices, 1, -1, NULL, NULL, &expect); + for (i = 0; i < 10; i++) + { + SetTextCharacterExtra(hdc, i); + pGetTextExtentExPointI(hdc, indices, 1, -1, NULL, NULL, &size); + ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i ); + } + SetTextCharacterExtra(hdc, 0); + + SetViewportExtEx( hdc, 3, 3, NULL ); + GetClientRect( hwnd, &clientArea ); + DPtoLP( hdc, (POINT *)&clientArea, 2 ); + testJustification(hdc, testText, &clientArea); + + GetTextExtentPoint32(hdc, "A", 1, &expect); + for (i = 0; i < 10; i++) + { + SetTextCharacterExtra(hdc, i); + GetTextExtentPoint32(hdc, "A", 1, &size); + ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i ); + } + +done: DeleteObject(hfont); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); @@ -2006,6 +2095,90 @@ skip("Symbol or Wingdings is not installed\n"); }
+static void test_GdiGetCodePage(void) +{ + static const struct _matching_data + { + UINT current_codepage; + LPCSTR lfFaceName; + UCHAR lfCharSet; + UINT expected_codepage; + } matching_data[] = { + {1251, "Arial", ANSI_CHARSET, 1252}, + {1251, "Tahoma", ANSI_CHARSET, 1252}, + + {1252, "Arial", ANSI_CHARSET, 1252}, + {1252, "Tahoma", ANSI_CHARSET, 1252}, + + {1253, "Arial", ANSI_CHARSET, 1252}, + {1253, "Tahoma", ANSI_CHARSET, 1252}, + + { 932, "Arial", ANSI_CHARSET, 1252}, /* Japanese Windows returns 1252, not 932 */ + { 932, "Tahoma", ANSI_CHARSET, 1252}, + { 932, "MS UI Gothic", ANSI_CHARSET, 1252}, + + { 936, "Arial", ANSI_CHARSET, 936}, + { 936, "Tahoma", ANSI_CHARSET, 936}, + { 936, "Simsun", ANSI_CHARSET, 936}, + + { 949, "Arial", ANSI_CHARSET, 949}, + { 949, "Tahoma", ANSI_CHARSET, 949}, + { 949, "Gulim", ANSI_CHARSET, 949}, + + { 950, "Arial", ANSI_CHARSET, 950}, + { 950, "Tahoma", ANSI_CHARSET, 950}, + { 950, "PMingLiU", ANSI_CHARSET, 950}, + }; + HDC hdc; + LOGFONT lf; + HFONT hfont; + UINT charset, acp; + DWORD codepage; + int i; + + if (!pGdiGetCodePage) + { + skip("GdiGetCodePage not available on this platform\n"); + return; + } + + acp = GetACP(); + + for (i = 0; i < sizeof(matching_data) / sizeof(struct _matching_data); i++) + { + /* only test data matched current locale codepage */ + if (matching_data[i].current_codepage != acp) + continue; + + if (!is_font_installed(matching_data[i].lfFaceName)) + { + skip("%s is not installed\n", matching_data[i].lfFaceName); + continue; + } + + hdc = GetDC(0); + + memset(&lf, 0, sizeof(lf)); + lf.lfHeight = -16; + lf.lfCharSet = matching_data[i].lfCharSet; + lstrcpyA(lf.lfFaceName, matching_data[i].lfFaceName); + hfont = CreateFontIndirectA(&lf); + ok(hfont != 0, "CreateFontIndirectA error %u\n", GetLastError()); + + hfont = SelectObject(hdc, hfont); + charset = GetTextCharset(hdc); + codepage = pGdiGetCodePage(hdc); + trace("acp=%d, lfFaceName=%s, lfCharSet=%d, GetTextCharset=%d, GdiGetCodePage=%d, expected codepage=%d\n", + acp, lf.lfFaceName, lf.lfCharSet, charset, codepage, matching_data[i].expected_codepage); + ok(codepage == matching_data[i].expected_codepage, + "GdiGetCodePage should have returned %d, got %d\n", matching_data[i].expected_codepage, codepage); + + hfont = SelectObject(hdc, hfont); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); + } +} + static void test_GetFontUnicodeRanges(void) { LOGFONTA lf; @@ -2057,6 +2230,12 @@ { int total; LOGFONT lf[MAX_ENUM_FONTS]; +}; + +struct enum_fullname_data +{ + int total; + ENUMLOGFONT elf[MAX_ENUM_FONTS]; };
struct enum_font_dataW @@ -2389,6 +2568,20 @@ return 1; }
+static INT CALLBACK enum_fullname_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + struct enum_fullname_data *efnd = (struct enum_fullname_data *)lParam; + + if (type != TRUETYPE_FONTTYPE) return 1; + + if (efnd->total < MAX_ENUM_FONTS) + efnd->elf[efnd->total++] = *(ENUMLOGFONT*)lf; + else + trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS); + + return 1; +} + static void test_EnumFontFamiliesEx_default_charset(void) { struct enum_font_data efd; @@ -2416,7 +2609,7 @@ } trace("'%s' has %d charsets.\n", gui_font.lfFaceName, efd.total);
- ok(efd.lf[0].lfCharSet == gui_font.lfCharSet, + ok(efd.lf[0].lfCharSet == gui_font.lfCharSet || broken(system_lang_id == LANG_ARABIC), "(%s) got charset %d expected %d\n", efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, gui_font.lfCharSet);
@@ -2760,11 +2953,15 @@ }
#define TT_PLATFORM_MICROSOFT 3 +#define TT_MS_ID_SYMBOL_CS 0 #define TT_MS_ID_UNICODE_CS 1 #define TT_MS_LANGID_ENGLISH_UNITED_STATES 0x0409 +#define TT_NAME_ID_FONT_FAMILY 1 +#define TT_NAME_ID_FONT_SUBFAMILY 2 +#define TT_NAME_ID_UNIQUE_ID 3 #define TT_NAME_ID_FULL_NAME 4
-static BOOL get_ttf_nametable_entry(HDC hdc, WORD name_id, char *out_buf, SIZE_T out_size) +static BOOL get_ttf_nametable_entry(HDC hdc, WORD name_id, WCHAR *out_buf, SIZE_T out_size, LCID language_id) { struct sfnt_name_header { @@ -2820,8 +3017,8 @@ for (i = 0; i < header->number_of_record; i++) { if (GET_BE_WORD(entry[i].platform_id) != TT_PLATFORM_MICROSOFT || - GET_BE_WORD(entry[i].encoding_id) != TT_MS_ID_UNICODE_CS || - GET_BE_WORD(entry[i].language_id) != TT_MS_LANGID_ENGLISH_UNITED_STATES || + (GET_BE_WORD(entry[i].encoding_id) != TT_MS_ID_UNICODE_CS && GET_BE_WORD(entry[i].encoding_id) != TT_MS_ID_SYMBOL_CS) || + GET_BE_WORD(entry[i].language_id) != language_id || GET_BE_WORD(entry[i].name_id) != name_id) { continue; @@ -3451,6 +3648,38 @@ DeleteDC(hdc); }
+static int CALLBACK create_fixed_pitch_font_proc(const LOGFONT *lpelfe, + const TEXTMETRIC *lpntme, + DWORD FontType, LPARAM lParam) +{ + const NEWTEXTMETRICEX *lpntmex = (const NEWTEXTMETRICEX *)lpntme; + CHARSETINFO csi; + LOGFONT lf = *lpelfe; + HFONT hfont; + + /* skip bitmap, proportional or vertical font */ + if ((FontType & TRUETYPE_FONTTYPE) == 0 || + (lf.lfPitchAndFamily & 0xf) != FIXED_PITCH || + lf.lfFaceName[0] == '@') + return 1; + + /* skip linked font */ + if (!TranslateCharsetInfo((DWORD*)(INT_PTR)lpelfe->lfCharSet, &csi, TCI_SRCCHARSET) || + (lpntmex->ntmFontSig.fsCsb[0] & csi.fs.fsCsb[0]) == 0) + return 1; + + /* test with an odd height */ + lf.lfHeight = -19; + lf.lfWidth = 0; + hfont = CreateFontIndirect(&lf); + if (hfont) + { + *(HFONT *)lParam = hfont; + return 0; + } + return 1; +} + static void test_GetGlyphOutline(void) { HDC hdc; @@ -3539,6 +3768,8 @@
for (i = 0; i < sizeof c / sizeof c[0]; ++i) { + static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}}; + lf.lfFaceName[0] = '\0'; lf.lfCharSet = c[i].cs; lf.lfPitchAndFamily = 0; @@ -3568,6 +3799,60 @@ /* expected to match wide-char version results */ ret2 = GetGlyphOutlineW(hdc, c[i].w, GGO_BITMAP, &gm2, 0, NULL, &mat); ok(ret == ret2 && memcmp(&gm, &gm2, sizeof gm) == 0, "%d %d\n", ret, ret2); + + if (EnumFontFamiliesEx(hdc, &lf, create_fixed_pitch_font_proc, (LPARAM)&hfont, 0)) + { + skip("Fixed-pitch TrueType font for charset %u is not available\n", c[i].cs); + continue; + } + DeleteObject(SelectObject(hdc, hfont)); + if (c[i].a <= 0xff) + { + DeleteObject(SelectObject(hdc, old_hfont)); + continue; + } + + ret = GetObject(hfont, sizeof lf, &lf); + ok(ret > 0, "GetObject error %u\n", GetLastError()); + + ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + trace("Tests with height=%d,half=%d,full=%d,face=%s,charset=%d\n", + -lf.lfHeight, gm.gmCellIncX, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet); + ok(gm2.gmCellIncX == gm.gmCellIncX * 2 || broken(gm2.gmCellIncX == -lf.lfHeight), + "expected %d, got %d (%s:%d)\n", + gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet); + + ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &rotate_mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + ok(gm2.gmCellIncY == -lf.lfHeight, + "expected %d, got %d (%s:%d)\n", + -lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet); + + lf.lfItalic = TRUE; + hfont = CreateFontIndirect(&lf); + ok(hfont != NULL, "CreateFontIndirect error %u\n", GetLastError()); + DeleteObject(SelectObject(hdc, hfont)); + ret = GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + ok(gm2.gmCellIncX == gm.gmCellIncX * 2 || broken(gm2.gmCellIncX == -lf.lfHeight), + "expected %d, got %d (%s:%d)\n", + gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet); + + lf.lfItalic = FALSE; + lf.lfEscapement = lf.lfOrientation = 2700; + hfont = CreateFontIndirect(&lf); + ok(hfont != NULL, "CreateFontIndirect error %u\n", GetLastError()); + DeleteObject(SelectObject(hdc, hfont)); + ret = GetGlyphOutlineA(hdc, c[i].a, GGO_METRICS, &gm2, 0, NULL, &mat); + ok(ret != GDI_ERROR, "GetGlyphOutlineA error %u\n", GetLastError()); + ok(gm2.gmCellIncY == -lf.lfHeight, + "expected %d, got %d (%s:%d)\n", + -lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet);
hfont = SelectObject(hdc, old_hfont); DeleteObject(hfont); @@ -3980,11 +4265,13 @@ static void test_fullname(void) { static const char *TestName[] = {"Lucida Sans Demibold Roman", "Lucida Sans Italic", "Lucida Sans Regular"}; - char buf[LF_FULLFACESIZE]; + WCHAR bufW[LF_FULLFACESIZE]; + char bufA[LF_FULLFACESIZE]; HFONT hfont, of; LOGFONTA lf; HDC hdc; int i; + DWORD ret;
hdc = CreateCompatibleDC(0); ok(hdc != NULL, "CreateCompatibleDC failed\n"); @@ -4011,14 +4298,196 @@ ok(hfont != 0, "CreateFontIndirectA failed\n");
of = SelectObject(hdc, hfont); - buf[0] = 0; - ok(get_ttf_nametable_entry(hdc, TT_NAME_ID_FULL_NAME, buf, sizeof(buf)), - "face full name could not be read\n"); - ok(!lstrcmpA(buf, TestName[i]), "font full names don't match: %s != %s\n", TestName[i], buf); + bufW[0] = 0; + bufA[0] = 0; + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FULL_NAME, bufW, sizeof(bufW), TT_MS_LANGID_ENGLISH_UNITED_STATES); + ok(ret, "face full name could not be read\n"); + WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, sizeof(bufA), NULL, FALSE); + ok(!lstrcmpA(bufA, TestName[i]), "font full names don't match: %s != %s\n", TestName[i], bufA); SelectObject(hdc, of); DeleteObject(hfont); } DeleteDC(hdc); +} + +static WCHAR *prepend_at(WCHAR *family) +{ + if (!family) + return NULL; + + memmove(family + 1, family, (lstrlenW(family) + 1) * sizeof(WCHAR)); + family[0] = '@'; + return family; +} + +static void test_fullname2_helper(const char *Family) +{ + char *FamilyName, *FaceName, *StyleName, *otmStr; + struct enum_fullname_data efnd; + WCHAR *bufW; + char *bufA; + HFONT hfont, of; + LOGFONTA lf; + HDC hdc; + int i; + DWORD otm_size, ret, buf_size; + OUTLINETEXTMETRICA *otm; + BOOL want_vertical, get_vertical; + want_vertical = ( Family[0] == '@' ); + + hdc = CreateCompatibleDC(0); + ok(hdc != NULL, "CreateCompatibleDC failed\n"); + + memset(&lf, 0, sizeof(lf)); + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfHeight = 16; + lf.lfWidth = 16; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfItalic = FALSE; + lf.lfWeight = FW_DONTCARE; + lstrcpy(lf.lfFaceName, Family); + efnd.total = 0; + EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0); + if (efnd.total == 0) + skip("%s is not installed\n", lf.lfFaceName); + + for (i = 0; i < efnd.total; i++) + { + FamilyName = (char *)efnd.elf[i].elfLogFont.lfFaceName; + FaceName = (char *)efnd.elf[i].elfFullName; + StyleName = (char *)efnd.elf[i].elfStyle; + + trace("Checking font %s:\nFamilyName: %s; FaceName: %s; StyleName: %s\n", Family, FamilyName, FaceName, StyleName); + + get_vertical = ( FamilyName[0] == '@' ); + ok(get_vertical == want_vertical, "Vertical flags don't match: %s %s\n", Family, FamilyName); + + lstrcpyA(lf.lfFaceName, FaceName); + hfont = CreateFontIndirectA(&lf); + ok(hfont != 0, "CreateFontIndirectA failed\n"); + + of = SelectObject(hdc, hfont); + buf_size = GetFontData(hdc, MS_NAME_TAG, 0, NULL, 0); + ok(buf_size != GDI_ERROR, "no name table found\n"); + if (buf_size == GDI_ERROR) continue; + + bufW = HeapAlloc(GetProcessHeap(), 0, buf_size); + bufA = HeapAlloc(GetProcessHeap(), 0, buf_size); + + otm_size = GetOutlineTextMetricsA(hdc, 0, NULL); + otm = HeapAlloc(GetProcessHeap(), 0, otm_size); + memset(otm, 0, otm_size); + ret = GetOutlineTextMetrics(hdc, otm_size, otm); + ok(ret != 0, "GetOutlineTextMetrics fails!\n"); + if (ret == 0) continue; + + bufW[0] = 0; + bufA[0] = 0; + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FONT_FAMILY, bufW, buf_size, GetSystemDefaultLangID()); + if (!ret) + { + trace("no localized FONT_FAMILY found.\n"); + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FONT_FAMILY, bufW, buf_size, TT_MS_LANGID_ENGLISH_UNITED_STATES); + } + ok(ret, "FAMILY (family name) could not be read\n"); + if (want_vertical) bufW = prepend_at(bufW); + WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); + ok(!lstrcmpA(FamilyName, bufA), "font family names don't match: returned %s, expect %s\n", FamilyName, bufA); + otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFamilyName; + ok(!lstrcmpA(FamilyName, otmStr), "FamilyName %s doesn't match otmpFamilyName %s\n", FamilyName, otmStr); + + bufW[0] = 0; + bufA[0] = 0; + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FULL_NAME, bufW, buf_size, GetSystemDefaultLangID()); + if (!ret) + { + trace("no localized FULL_NAME found.\n"); + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FULL_NAME, bufW, buf_size, TT_MS_LANGID_ENGLISH_UNITED_STATES); + } + ok(ret, "FULL_NAME (face name) could not be read\n"); + if (want_vertical) bufW = prepend_at(bufW); + WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); + ok(!lstrcmpA(FaceName, bufA), "font face names don't match: returned %s, expect %s\n", FaceName, bufA); + otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFaceName; + ok(!lstrcmpA(FaceName, otmStr), "FaceName %s doesn't match otmpFaceName %s\n", FaceName, otmStr); + + bufW[0] = 0; + bufA[0] = 0; + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FONT_SUBFAMILY, bufW, buf_size, GetSystemDefaultLangID()); + if (!ret) + { + trace("no localized FONT_SUBFAMILY found.\n"); + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_FONT_SUBFAMILY, bufW, buf_size, TT_MS_LANGID_ENGLISH_UNITED_STATES); + } + ok(ret, "SUBFAMILY (style name) could not be read\n"); + WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); + ok(!lstrcmpA(StyleName, bufA), "style names don't match: returned %s, expect %s\n", StyleName, bufA); + otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpStyleName; + ok(!lstrcmpA(StyleName, otmStr), "StyleName %s doesn't match otmpStyleName %s\n", StyleName, otmStr); + + bufW[0] = 0; + bufA[0] = 0; + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_UNIQUE_ID, bufW, buf_size, GetSystemDefaultLangID()); + if (!ret) + { + trace("no localized UNIQUE_ID found.\n"); + ret = get_ttf_nametable_entry(hdc, TT_NAME_ID_UNIQUE_ID, bufW, buf_size, TT_MS_LANGID_ENGLISH_UNITED_STATES); + } + ok(ret, "UNIQUE_ID (full name) could not be read\n"); + WideCharToMultiByte(CP_ACP, 0, bufW, -1, bufA, buf_size, NULL, FALSE); + otmStr = (LPSTR)otm + (UINT_PTR)otm->otmpFullName; + ok(!lstrcmpA(otmStr, bufA), "UNIQUE ID (full name) doesn't match: returned %s, expect %s\n", otmStr, bufA); + + SelectObject(hdc, of); + DeleteObject(hfont); + + HeapFree(GetProcessHeap(), 0, otm); + HeapFree(GetProcessHeap(), 0, bufW); + HeapFree(GetProcessHeap(), 0, bufA); + } + DeleteDC(hdc); +} + +static void test_fullname2(void) +{ + test_fullname2_helper("Arial"); + test_fullname2_helper("DejaVu Sans"); + test_fullname2_helper("Lucida Sans"); + test_fullname2_helper("Tahoma"); + test_fullname2_helper("Webdings"); + test_fullname2_helper("Wingdings"); + test_fullname2_helper("SimSun"); + test_fullname2_helper("NSimSun"); + test_fullname2_helper("MingLiu"); + test_fullname2_helper("PMingLiu"); + test_fullname2_helper("WenQuanYi Micro Hei"); + test_fullname2_helper("MS UI Gothic"); + test_fullname2_helper("Ume UI Gothic"); + test_fullname2_helper("MS Gothic"); + test_fullname2_helper("Ume Gothic"); + test_fullname2_helper("MS PGothic"); + test_fullname2_helper("Ume P Gothic"); + test_fullname2_helper("Gulim"); + test_fullname2_helper("Batang"); + test_fullname2_helper("UnBatang"); + test_fullname2_helper("UnDotum"); + test_fullname2_helper("@SimSun"); + test_fullname2_helper("@NSimSun"); + test_fullname2_helper("@MingLiu"); + test_fullname2_helper("@PMingLiu"); + test_fullname2_helper("@WenQuanYi Micro Hei"); + test_fullname2_helper("@MS UI Gothic"); + test_fullname2_helper("@Ume UI Gothic"); + test_fullname2_helper("@MS Gothic"); + test_fullname2_helper("@Ume Gothic"); + test_fullname2_helper("@MS PGothic"); + test_fullname2_helper("@Ume P Gothic"); + test_fullname2_helper("@Gulim"); + test_fullname2_helper("@Batang"); + test_fullname2_helper("@UnBatang"); + test_fullname2_helper("@UnDotum"); + }
static BOOL write_ttf_file(const char *fontname, char *tmp_name) @@ -4063,6 +4532,46 @@ return ret; }
+static void test_GetGlyphOutline_empty_contour(void) +{ + HDC hdc; + LOGFONTA lf; + HFONT hfont, hfont_prev; + TTPOLYGONHEADER *header; + GLYPHMETRICS gm; + char buf[1024]; + DWORD ret; + + 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_prev = SelectObject(hdc, hfont); + ok(hfont_prev != NULL, "SelectObject failed\n"); + + ret = GetGlyphOutlineW(hdc, 0xa8, GGO_NATIVE, &gm, 0, NULL, &mat); + ok(ret == 228, "GetGlyphOutline returned %d, expected 228\n", ret); + + header = (TTPOLYGONHEADER*)buf; + ret = GetGlyphOutlineW(hdc, 0xa8, GGO_NATIVE, &gm, sizeof(buf), buf, &mat); + ok(ret == 228, "GetGlyphOutline returned %d, expected 228\n", ret); + ok(header->cb == 36, "header->cb = %d, expected 36\n", header->cb); + ok(header->dwType == TT_POLYGON_TYPE, "header->dwType = %d, expected TT_POLYGON_TYPE\n", header->dwType); + header = (TTPOLYGONHEADER*)((char*)header+header->cb); + ok(header->cb == 96, "header->cb = %d, expected 96\n", header->cb); + header = (TTPOLYGONHEADER*)((char*)header+header->cb); + ok(header->cb == 96, "header->cb = %d, expected 96\n", header->cb); + + SelectObject(hdc, hfont_prev); + DeleteObject(hfont); + ReleaseDC(NULL, hdc); +} + static void test_CreateScalableFontResource(void) { char ttf_name[MAX_PATH]; @@ -4070,6 +4579,7 @@ char fot_name[MAX_PATH]; char *file_part; DWORD ret; + int i;
if (!pAddFontResourceExA || !pRemoveFontResourceExA) { @@ -4126,7 +4636,6 @@ ok(ret, "DeleteFile() error %d\n", GetLastError());
ret = pRemoveFontResourceExA(fot_name, 0, 0); -todo_wine ok(!ret, "RemoveFontResourceEx() should fail\n");
/* test public font resource */ @@ -4144,8 +4653,9 @@ ret = is_truetype_font_installed("wine_test"); ok(ret, "font wine_test should be enumerated\n");
+ test_GetGlyphOutline_empty_contour(); + ret = pRemoveFontResourceExA(fot_name, FR_PRIVATE, 0); -todo_wine ok(!ret, "RemoveFontResourceEx() with not matching flags should fail\n");
SetLastError(0xdeadbeef); @@ -4153,21 +4663,27 @@ ok(ret, "RemoveFontResourceEx() error %d\n", GetLastError());
ret = is_truetype_font_installed("wine_test"); -todo_wine ok(!ret, "font wine_test should not be enumerated\n"); - - /* FIXME: since RemoveFontResource is a stub correct testing is impossible */ - if (ret) - { - /* remove once RemoveFontResource is implemented */ - DeleteFile(fot_name); - DeleteFile(ttf_name); - return; - }
ret = pRemoveFontResourceExA(fot_name, 0, 0); ok(!ret, "RemoveFontResourceEx() should fail\n");
+ /* test refcounting */ + for (i = 0; i < 5; i++) + { + SetLastError(0xdeadbeef); + ret = pAddFontResourceExA(fot_name, 0, 0); + ok(ret, "AddFontResourceEx() error %d\n", GetLastError()); + } + for (i = 0; i < 5; i++) + { + SetLastError(0xdeadbeef); + ret = pRemoveFontResourceExA(fot_name, 0, 0); + ok(ret, "RemoveFontResourceEx() error %d\n", GetLastError()); + } + ret = pRemoveFontResourceExA(fot_name, 0, 0); + ok(!ret, "RemoveFontResourceEx() should fail\n"); + DeleteFile(fot_name);
/* test hidden font resource */ @@ -4183,6 +4699,7 @@ ok(ret, "AddFontResourceEx() error %d\n", GetLastError());
ret = is_truetype_font_installed("wine_test"); + todo_wine ok(!ret, "font wine_test should not be enumerated\n");
/* XP allows removing a private font added with 0 flags */ @@ -4353,10 +4870,139 @@ ReleaseDC(NULL, hdc); }
+static int get_font_dpi(const LOGFONT *lf) +{ + HDC hdc = CreateCompatibleDC(0); + HFONT hfont; + TEXTMETRIC tm; + int ret; + + hfont = CreateFontIndirect(lf); + ok(hfont != 0, "CreateFontIndirect failed\n"); + + SelectObject(hdc, hfont); + ret = GetTextMetrics(hdc, &tm); + ok(ret, "GetTextMetrics failed\n"); + ret = tm.tmDigitizedAspectX; + + DeleteDC(hdc); + DeleteObject(hfont); + + return ret; +} + +static void test_stock_fonts(void) +{ + static const int font[] = + { + ANSI_FIXED_FONT, ANSI_VAR_FONT, SYSTEM_FONT, DEVICE_DEFAULT_FONT, DEFAULT_GUI_FONT + /* SYSTEM_FIXED_FONT, OEM_FIXED_FONT */ + }; + static const struct test_data + { + int charset, weight, height, dpi; + const char face_name[LF_FACESIZE]; + } td[][11] = + { + { /* ANSI_FIXED_FONT */ + { DEFAULT_CHARSET, FW_NORMAL, 12, 96, "Courier" }, + { DEFAULT_CHARSET, FW_NORMAL, 12, 120, "Courier" }, + { 0 } + }, + { /* ANSI_VAR_FONT */ + { DEFAULT_CHARSET, FW_NORMAL, 12, 96, "MS Sans Serif" }, + { DEFAULT_CHARSET, FW_NORMAL, 12, 120, "MS Sans Serif" }, + { 0 } + }, + { /* SYSTEM_FONT */ + { SHIFTJIS_CHARSET, FW_NORMAL, 18, 96, "System" }, + { SHIFTJIS_CHARSET, FW_NORMAL, 22, 120, "System" }, + { HANGEUL_CHARSET, FW_NORMAL, 16, 96, "System" }, + { HANGEUL_CHARSET, FW_NORMAL, 20, 120, "System" }, + { DEFAULT_CHARSET, FW_BOLD, 16, 96, "System" }, + { DEFAULT_CHARSET, FW_BOLD, 20, 120, "System" }, + { 0 } + }, + { /* DEVICE_DEFAULT_FONT */ + { SHIFTJIS_CHARSET, FW_NORMAL, 18, 96, "System" }, + { SHIFTJIS_CHARSET, FW_NORMAL, 22, 120, "System" }, + { HANGEUL_CHARSET, FW_NORMAL, 16, 96, "System" }, + { HANGEUL_CHARSET, FW_NORMAL, 20, 120, "System" }, + { DEFAULT_CHARSET, FW_BOLD, 16, 96, "System" }, + { DEFAULT_CHARSET, FW_BOLD, 20, 120, "System" }, + { 0 } + }, + { /* DEFAULT_GUI_FONT */ + { SHIFTJIS_CHARSET, FW_NORMAL, -12, 96, "?MS UI Gothic" }, + { SHIFTJIS_CHARSET, FW_NORMAL, -15, 120, "?MS UI Gothic" }, + { HANGEUL_CHARSET, FW_NORMAL, -12, 96, "?Gulim" }, + { HANGEUL_CHARSET, FW_NORMAL, -15, 120, "?Gulim" }, + { GB2312_CHARSET, FW_NORMAL, -12, 96, "?SimHei" }, + { GB2312_CHARSET, FW_NORMAL, -15, 120, "?SimHei" }, + { CHINESEBIG5_CHARSET, FW_NORMAL, -12, 96, "?MingLiU" }, + { CHINESEBIG5_CHARSET, FW_NORMAL, -15, 120, "?MingLiU" }, + { DEFAULT_CHARSET, FW_NORMAL, -11, 96, "MS Shell Dlg" }, + { DEFAULT_CHARSET, FW_NORMAL, -13, 120, "MS Shell Dlg" }, + { 0 } + } + }; + int i, j; + + for (i = 0; i < sizeof(font)/sizeof(font[0]); i++) + { + HFONT hfont; + LOGFONT lf; + int ret; + + hfont = GetStockObject(font[i]); + ok(hfont != 0, "%d: GetStockObject(%d) failed\n", i, font[i]); + + ret = GetObject(hfont, sizeof(lf), &lf); + if (ret != sizeof(lf)) + { + /* NT4 */ + win_skip("%d: GetObject returned %d instead of sizeof(LOGFONT)\n", i, ret); + continue; + } + + for (j = 0; td[i][j].face_name[0] != 0; j++) + { + if (lf.lfCharSet != td[i][j].charset && td[i][j].charset != DEFAULT_CHARSET) + { + continue; + } + + ret = get_font_dpi(&lf); + if (ret != td[i][j].dpi) + { + trace("%d(%d): font %s %d dpi doesn't match test data %d\n", + i, j, lf.lfFaceName, ret, td[i][j].dpi); + continue; + } + + ok(td[i][j].weight == lf.lfWeight, "%d(%d): expected lfWeight %d, got %d\n", i, j, td[i][j].weight, lf.lfWeight); + ok(td[i][j].height == lf.lfHeight, "%d(%d): expected lfHeight %d, got %d\n", i, j, td[i][j].height, lf.lfHeight); + if (td[i][j].face_name[0] == '?') + { + /* Wine doesn't have this font, skip this case for now. + Actually, the face name is localized on Windows and varies + dpending on Windows versions (e.g. Japanese NT4 vs win2k). */ + trace("%d(%d): default gui font is %s\n", i, j, lf.lfFaceName); + } + else + { + ok(!lstrcmp(td[i][j].face_name, lf.lfFaceName), "%d(%d): expected lfFaceName %s, got %s\n", i, j, td[i][j].face_name, lf.lfFaceName); + } + break; + } + } +} + START_TEST(font) { init();
+ test_stock_fonts(); test_logfont(); test_bitmap_font(); test_outline_font(); @@ -4369,6 +5015,7 @@ test_GetOutlineTextMetrics(); test_SetTextJustification(); test_font_charset(); + test_GdiGetCodePage(); test_GetFontUnicodeRanges(); test_nonexistent_font(); test_orientation(); @@ -4405,6 +5052,7 @@ test_CreateFontIndirectEx(); test_oemcharset(); test_fullname(); + test_fullname2(); test_east_asian_font_selection();
/* These tests should be last test until RemoveFontResource
Modified: trunk/rostests/winetests/gdi32/gdiobj.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/gdiobj.c?r... ============================================================================== --- trunk/rostests/winetests/gdi32/gdiobj.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/gdiobj.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -319,10 +319,54 @@ DeleteObject(hrgn); }
+static void test_handles_on_win64(void) +{ + int i; + BOOL ret; + DWORD type; + HRGN hrgn, hrgn_test; + + static const struct + { + ULONG high; + ULONG low; + BOOL ret; + } cases[] = + { + { 0x00000000, 0x00000000, TRUE }, + { 0x00000000, 0x0000ffe0, FALSE }, /* just over MAX_LARGE_HANDLES */ + { 0x00000000, 0x0000ffb0, FALSE }, /* just under MAX_LARGE_HANDLES */ + { 0xffffffff, 0xffff0000, FALSE }, + { 0xffffffff, 0x00000000, TRUE }, + { 0xdeadbeef, 0x00000000, TRUE }, + { 0xcccccccc, 0xcccccccc, FALSE } + }; + + if (sizeof(void*) != 8) + return; + + for (i = 0; i < sizeof(cases)/sizeof(cases[0]); i++) + { + hrgn = CreateRectRgn(10, 10, 20, 20); + hrgn_test = (HRGN)(ULONG_PTR)((ULONG_PTR)hrgn | ((ULONGLONG)cases[i].high << 32) | cases[i].low); + type = GetObjectType( hrgn_test ); + if (cases[i].ret) + ok( type == OBJ_REGION, "wrong type %u\n", type ); + else + ok( type == 0, "wrong type %u\n", type ); + ret = DeleteObject(hrgn_test); + ok( cases[i].ret == ret, "DeleteObject should return %s (%p)\n", + cases[i].ret ? "TRUE" : "FALSE", hrgn_test); + /* actually free it if above is expected to fail */ + if (!ret) DeleteObject(hrgn); + } +} + START_TEST(gdiobj) { test_gdi_objects(); test_thread_objects(); test_GetCurrentObject(); test_region(); -} + test_handles_on_win64(); +}
Modified: trunk/rostests/winetests/gdi32/metafile.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/metafile.c... ============================================================================== --- trunk/rostests/winetests/gdi32/metafile.c [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/metafile.c [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -58,6 +58,20 @@ GDI_GET_PROC(SetRelAbs); GDI_GET_PROC(SetDCBrushColor); GDI_GET_PROC(SetDCPenColor); +} + +static DWORD rgn_rect_count(HRGN hrgn) +{ + DWORD size; + RGNDATA *data; + + if (!hrgn) return 0; + if (!(size = GetRegionData(hrgn, 0, NULL))) return 0; + if (!(data = HeapAlloc(GetProcessHeap(), 0, size))) return 0; + GetRegionData(hrgn, size, data); + size = data->rdh.nCount; + HeapFree(GetProcessHeap(), 0, data); + return size; }
static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, @@ -2483,19 +2497,183 @@ SetRect(&rc_sclip, 100, 100, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); hrgn = CreateRectRgn(rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom); SelectClipRgn(hdc, hrgn); + SetRect(&rc_res, -1, -1, -1, -1); ret = GetClipBox(hdc, &rc_res); -todo_wine ok(ret == SIMPLEREGION, "got %d\n", ret); - if(ret == SIMPLEREGION) - ok(EqualRect(&rc_res, &rc_sclip), - "expected rc_res (%d, %d) - (%d, %d), got (%d, %d) - (%d, %d)\n", - rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom, - rc_res.left, rc_res.top, rc_res.right, rc_res.bottom); + ok(EqualRect(&rc_res, &rc_sclip), + "expected (%d,%d)-(%d,%d), got (%d,%d)-(%d,%d)\n", + rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom, + rc_res.left, rc_res.top, rc_res.right, rc_res.bottom); + + OffsetRect(&rc_sclip, -100, -100); + ret = OffsetClipRgn(hdc, -100, -100); + ok(ret == SIMPLEREGION, "got %d\n", ret); + SetRect(&rc_res, -1, -1, -1, -1); + ret = GetClipBox(hdc, &rc_res); + ok(ret == SIMPLEREGION, "got %d\n", ret); + ok(EqualRect(&rc_res, &rc_sclip), + "expected (%d,%d)-(%d,%d), got (%d,%d)-(%d,%d)\n", + rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom, + rc_res.left, rc_res.top, rc_res.right, rc_res.bottom); + + ret = IntersectClipRect(hdc, 0, 0, 100, 100); + ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret); + if (ret == COMPLEXREGION) + { + /* XP returns COMPLEXREGION although region contains only 1 rect */ + ret = GetClipRgn(hdc, hrgn); + ok(ret == 1, "expected 1, got %d\n", ret); + ret = rgn_rect_count(hrgn); + ok(ret == 1, "expected 1, got %d\n", ret); + } + SetRect(&rc_res, -1, -1, -1, -1); + ret = GetClipBox(hdc, &rc_res); + ok(ret == SIMPLEREGION, "got %d\n", ret); + ok(EqualRect(&rc_res, &rc), + "expected (%d,%d)-(%d,%d), got (%d,%d)-(%d,%d)\n", + rc.left, rc.top, rc.right, rc.bottom, + rc_res.left, rc_res.top, rc_res.right, rc_res.bottom); + + SetRect(&rc_sclip, 0, 0, 100, 50); + ret = ExcludeClipRect(hdc, 0, 50, 100, 100); + ok(ret == SIMPLEREGION || broken(ret == COMPLEXREGION) /* XP */, "got %d\n", ret); + if (ret == COMPLEXREGION) + { + /* XP returns COMPLEXREGION although region contains only 1 rect */ + ret = GetClipRgn(hdc, hrgn); + ok(ret == 1, "expected 1, got %d\n", ret); + ret = rgn_rect_count(hrgn); + ok(ret == 1, "expected 1, got %d\n", ret); + } + SetRect(&rc_res, -1, -1, -1, -1); + ret = GetClipBox(hdc, &rc_res); + ok(ret == SIMPLEREGION, "got %d\n", ret); + ok(EqualRect(&rc_res, &rc_sclip), + "expected (%d,%d)-(%d,%d), got (%d,%d)-(%d,%d)\n", + rc_sclip.left, rc_sclip.top, rc_sclip.right, rc_sclip.bottom, + rc_res.left, rc_res.top, rc_res.right, rc_res.bottom);
hemf = CloseEnhMetaFile(hdc); DeleteEnhMetaFile(hemf); DeleteObject(hrgn); - DeleteDC(hdc); +} + +static const unsigned char MF_CLIP_BITS[] = { + /* METAHEADER */ + 0x01, 0x00, /* mtType */ + 0x09, 0x00, /* mtHeaderSize */ + 0x00, 0x03, /* mtVersion */ + 0x32, 0x00, 0x00, 0x00, /* mtSize */ + 0x01, 0x00, /* mtNoObjects */ + 0x14, 0x00, 0x00, 0x00, /* mtMaxRecord (size in words of longest record) */ + 0x00, 0x00, /* reserved */ + + /* METARECORD for CreateRectRgn(0x11, 0x22, 0x33, 0x44) */ + 0x14, 0x00, 0x00, 0x00, /* rdSize in words */ + 0xff, 0x06, /* META_CREATEREGION */ + 0x00, 0x00, 0x06, 0x00, 0xf6, 0x02, 0x00, 0x00, + 0x24, 0x00, 0x01, 0x00, 0x02, 0x00, 0x11, 0x00, + 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x02, 0x00, + 0x22, 0x00, 0x44, 0x00, 0x11, 0x00, 0x33, 0x00, + 0x02, 0x00, + + /* METARECORD for SelectObject */ + 0x04, 0x00, 0x00, 0x00, + 0x2d, 0x01, /* META_SELECTOBJECT (not META_SELECTCLIPREGION?!) */ + 0x00, 0x00, + + /* METARECORD */ + 0x04, 0x00, 0x00, 0x00, + 0xf0, 0x01, /* META_DELETEOBJECT */ + 0x00, 0x00, + + /* METARECORD for MoveTo(1,0x30) */ + 0x05, 0x00, 0x00, 0x00, /* rdSize in words */ + 0x14, 0x02, /* META_MOVETO */ + 0x30, 0x00, /* y */ + 0x01, 0x00, /* x */ + + /* METARECORD for LineTo(0x20, 0x30) */ + 0x05, 0x00, 0x00, 0x00, /* rdSize in words */ + 0x13, 0x02, /* META_LINETO */ + 0x30, 0x00, /* y */ + 0x20, 0x00, /* x */ + + /* EOF */ + 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00 +}; + +static int clip_mf_enum_proc_seen_selectclipregion; +static int clip_mf_enum_proc_seen_selectobject; + +static int CALLBACK clip_mf_enum_proc(HDC hdc, HANDLETABLE *handle_table, + METARECORD *mr, int n_objs, LPARAM param) +{ + switch (mr->rdFunction) { + case META_SELECTCLIPREGION: + clip_mf_enum_proc_seen_selectclipregion++; + break; + case META_SELECTOBJECT: + clip_mf_enum_proc_seen_selectobject++; + break; + } + return 1; +} + +static void test_mf_clipping(void) +{ + /* left top right bottom */ + static RECT rc_clip = { 0x11, 0x22, 0x33, 0x44 }; + HWND hwnd; + HDC hdc; + HMETAFILE hmf; + HRGN hrgn; + INT ret; + + SetLastError(0xdeadbeef); + hdc = CreateMetaFileA(NULL); + ok(hdc != 0, "CreateMetaFileA error %d\n", GetLastError()); + + hrgn = CreateRectRgn(rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); + ret = SelectClipRgn(hdc, hrgn); + /* Seems like it should be SIMPLEREGION, but windows returns NULLREGION? */ + ok(ret == NULLREGION, "expected NULLREGION, got %d\n", ret); + + /* Draw a line that starts off left of the clip region and ends inside it */ + MoveToEx(hdc, 0x1, 0x30, NULL); + LineTo(hdc, 0x20, 0x30); + + SetLastError(0xdeadbeef); + hmf = CloseMetaFile(hdc); + ok(hmf != 0, "CloseMetaFile error %d\n", GetLastError()); + + if (compare_mf_bits(hmf, MF_CLIP_BITS, sizeof(MF_CLIP_BITS), + "mf_clipping") != 0) + { + dump_mf_bits(hmf, "mf_clipping"); + } + + DeleteObject(hrgn); + + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE, + 0, 0, 200, 200, 0, 0, 0, NULL); + ok(hwnd != 0, "CreateWindowExA error %d\n", GetLastError()); + + hdc = GetDC(hwnd); + + ret = EnumMetaFile(hdc, hmf, clip_mf_enum_proc, (LPARAM)&rc_clip); + ok(ret, "EnumMetaFile error %d\n", GetLastError()); + + /* Oddly, windows doesn't seem to use META_SELECTCLIPREGION */ + ok(clip_mf_enum_proc_seen_selectclipregion == 0, + "expected 0 selectclipregion, saw %d\n", clip_mf_enum_proc_seen_selectclipregion); + ok(clip_mf_enum_proc_seen_selectobject == 1, + "expected 1 selectobject, saw %d\n", clip_mf_enum_proc_seen_selectobject); + + DeleteMetaFile(hmf); + ReleaseDC(hwnd, hdc); + DestroyWindow(hwnd); }
static INT CALLBACK EmfEnumProc(HDC hdc, HANDLETABLE *lpHTable, const ENHMETARECORD *lpEMFR, INT nObj, LPARAM lpData) @@ -3211,6 +3389,9 @@ test_SaveDC(); test_emf_BitBlt(); test_emf_DCBrush(); + test_emf_ExtTextOut_on_path(); + test_emf_clipping(); + test_emf_polybezier();
/* For win-format metafiles (mfdrv) */ test_mf_SaveDC(); @@ -3221,9 +3402,7 @@ test_CopyMetaFile(); test_SetMetaFileBits(); test_mf_ExtTextOut_on_path(); - test_emf_ExtTextOut_on_path(); - test_emf_clipping(); - test_emf_polybezier(); + test_mf_clipping();
/* For metafile conversions */ test_mf_conversions();
Modified: trunk/rostests/winetests/gdi32/wine_test.sfd URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/wine_test.... ============================================================================== --- trunk/rostests/winetests/gdi32/wine_test.sfd [iso-8859-1] (original) +++ trunk/rostests/winetests/gdi32/wine_test.sfd [iso-8859-1] Sat Mar 16 15:01:33 2013 @@ -20,7 +20,7 @@ OS2_WeightWidthSlopeOnly: 0 OS2_UseTypoMetrics: 1 CreationTime: 1288336343 -ModificationTime: 1288336873 +ModificationTime: 1352483620 PfmFamily: 17 TTFWeight: 500 TTFWidth: 5 @@ -86,7 +86,7 @@ AntiAlias: 1 FitToEm: 1 WinInfo: 65 65 19 -BeginChars: 65539 4 +BeginChars: 65539 5
StartChar: .notdef Encoding: 65536 -1 0 @@ -176,5 +176,30 @@ Flags: W LayerCount: 2 EndChar + +StartChar: dieresis +Encoding: 168 168 0 +Width: 1000 +VWidth: 0 +Flags: HW +LayerCount: 2 +Fore +SplineSet +620.215 824.429 m 1,0,1 + 760.84 777.554 760.84 777.554 713.965 636.929 c 1,2,-1 + 620.215 824.429 l 1,0,1 +154.883 324.971 m 0,3,-1 +254.492 773.213 m 1,4,5 + 310.707 834.805 310.707 834.805 374.609 767.354 c 1,6,7 + 410.471 728.672 410.471 728.672 374.609 691.182 c 0,8,9 + 308.375 621.934 308.375 621.934 254.492 688.252 c 0,10,11 + 216.406 735.127 216.406 735.127 254.492 773.213 c 1,4,5 +254.492 773.213 m 1,12,13 + 216.406 735.127 216.406 735.127 254.492 688.252 c 0,14,15 + 308.375 621.934 308.375 621.934 374.609 691.182 c 0,16,17 + 410.471 728.672 410.471 728.672 374.609 767.354 c 1,18,19 + 310.707 834.805 310.707 834.805 254.492 773.213 c 1,12,13 +EndSplineSet +EndChar EndChars EndSplineFont
Modified: trunk/rostests/winetests/gdi32/wine_test.ttf URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/gdi32/wine_test.... ============================================================================== Binary files - no diff available.