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/CMakeList…
==============================================================================
--- 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?…
==============================================================================
--- 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.…
==============================================================================
--- 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=…
==============================================================================
--- 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?re…
==============================================================================
--- 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?…
==============================================================================
--- 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.…
==============================================================================
--- 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.