[GDI32_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 20 Apr 2014 13:01:01 +0000 (13:01 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 20 Apr 2014 13:01:01 +0000 (13:01 +0000)
* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62835

22 files changed:
rostests/winetests/gdi32/CMakeLists.txt
rostests/winetests/gdi32/bitmap.c
rostests/winetests/gdi32/brush.c
rostests/winetests/gdi32/clipping.c
rostests/winetests/gdi32/dc.c
rostests/winetests/gdi32/dib.c
rostests/winetests/gdi32/font.c
rostests/winetests/gdi32/gdiobj.c
rostests/winetests/gdi32/generated.c
rostests/winetests/gdi32/mapping.c
rostests/winetests/gdi32/metafile.c
rostests/winetests/gdi32/palette.c
rostests/winetests/gdi32/path.c
rostests/winetests/gdi32/pen.c
rostests/winetests/gdi32/resource.rc
rostests/winetests/gdi32/testlist.c
rostests/winetests/gdi32/vertical.sfd
rostests/winetests/gdi32/vertical.ttf
rostests/winetests/gdi32/wine_test.sfd
rostests/winetests/gdi32/wine_test.ttf
rostests/winetests/gdi32/wine_vdmx.sfd [new file with mode: 0644]
rostests/winetests/gdi32/wine_vdmx.ttf [new file with mode: 0644]

index 90dede3..908ea21 100644 (file)
@@ -19,7 +19,9 @@ list(APPEND SOURCE
     testlist.c)
 
 add_executable(gdi32_winetest ${SOURCE} resource.rc)
-
 set_module_type(gdi32_winetest win32cui)
-add_importlibs(gdi32_winetest gdi32 user32 advapi32 msvcrt kernel32 ntdll)
+add_importlibs(gdi32_winetest gdi32 user32 advapi32 msvcrt kernel32)
+if(MSVC)
+    add_importlibs(gdi32_winetest ntdll)
+endif()
 add_cd_file(TARGET gdi32_winetest DESTINATION reactos/bin FOR all)
index 84f1d11..bb021a4 100755 (executable)
@@ -59,7 +59,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
     INT ret, width_bytes;
     BYTE buf[512], buf_cmp[512];
 
-    ret = GetObject(hbm, sizeof(bm), &bm);
+    ret = GetObjectW(hbm, sizeof(bm), &bm);
     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
 
     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
@@ -88,19 +88,19 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
         "buffers do not match, depth %d\n", bmih->biBitCount);
 
     /* test various buffer sizes for GetObject */
-    ret = GetObject(hbm, sizeof(*bma) * 2, bma);
+    ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
 
-    ret = GetObject(hbm, sizeof(bm) / 2, &bm);
+    ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 0, &bm);
+    ret = GetObjectW(hbm, 0, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 1, &bm);
+    ret = GetObjectW(hbm, 1, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 0, NULL);
+    ret = GetObjectW(hbm, 0, NULL);
     ok(ret == sizeof(bm), "wrong size %d\n", ret);
 }
 
@@ -248,7 +248,7 @@ static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER
     INT ret, bm_width_bytes, dib_width_bytes;
     BYTE *buf;
 
-    ret = GetObject(hbm, sizeof(bm), &bm);
+    ret = GetObjectW(hbm, sizeof(bm), &bm);
     ok(ret == sizeof(bm), "GetObject returned %d\n", ret);
 
     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
@@ -280,30 +280,30 @@ static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER
 
     /* test various buffer sizes for GetObject */
     memset(&ds, 0xAA, sizeof(ds));
-    ret = GetObject(hbm, sizeof(*bma) * 2, bma);
+    ret = GetObjectW(hbm, sizeof(*bma) * 2, bma);
     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
     ok(bm.bmWidth == bmih->biWidth, "wrong bm.bmWidth %d\n", bm.bmWidth);
     ok(bm.bmHeight == abs(bmih->biHeight), "wrong bm.bmHeight %d\n", bm.bmHeight);
     ok(bm.bmBits == bits, "wrong bm.bmBits %p != %p\n", bm.bmBits, bits);
 
-    ret = GetObject(hbm, sizeof(bm) / 2, &bm);
+    ret = GetObjectW(hbm, sizeof(bm) / 2, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 0, &bm);
+    ret = GetObjectW(hbm, 0, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 1, &bm);
+    ret = GetObjectW(hbm, 1, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
     /* test various buffer sizes for GetObject */
-    ret = GetObject(hbm, 0, NULL);
+    ret = GetObjectW(hbm, 0, NULL);
     ok(ret == sizeof(bm), "wrong size %d\n", ret);
 
-    ret = GetObject(hbm, sizeof(*dsa) * 2, dsa);
+    ret = GetObjectW(hbm, sizeof(*dsa) * 2, dsa);
     ok(ret == sizeof(*dsa), "wrong size %d\n", ret);
 
     memset(&ds, 0xAA, sizeof(ds));
-    ret = GetObject(hbm, sizeof(ds), &ds);
+    ret = GetObjectW(hbm, sizeof(ds), &ds);
     ok(ret == sizeof(ds), "wrong size %d\n", ret);
 
     ok(ds.dsBm.bmBits == bits, "wrong bm.bmBits %p != %p\n", ds.dsBm.bmBits, bits);
@@ -326,16 +326,16 @@ static void test_dib_info(HBITMAP hbm, const void *bits, const BITMAPINFOHEADER
     ok(ds.dsBmih.biYPelsPerMeter == bmih->biYPelsPerMeter, "%d != %d\n", ds.dsBmih.biYPelsPerMeter, bmih->biYPelsPerMeter);
 
     memset(&ds, 0xAA, sizeof(ds));
-    ret = GetObject(hbm, sizeof(ds) - 4, &ds);
+    ret = GetObjectW(hbm, sizeof(ds) - 4, &ds);
     ok(ret == sizeof(ds.dsBm), "wrong size %d\n", ret);
     ok(ds.dsBm.bmWidth == bmih->biWidth, "%d != %d\n", ds.dsBmih.biWidth, bmih->biWidth);
     ok(ds.dsBm.bmHeight == abs(bmih->biHeight), "%d != %d\n", ds.dsBmih.biHeight, abs(bmih->biHeight));
     ok(ds.dsBm.bmBits == bits, "%p != %p\n", ds.dsBm.bmBits, bits);
 
-    ret = GetObject(hbm, 0, &ds);
+    ret = GetObjectW(hbm, 0, &ds);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbm, 1, &ds);
+    ret = GetObjectW(hbm, 1, &ds);
     ok(ret == 0, "%d != 0\n", ret);
 }
 
@@ -457,7 +457,7 @@ static void test_dibsections(void)
 
     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection error %d\n", GetLastError());
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
     ok(dibsec.dsBm.bmBits == bits, "dibsec.dsBits %p != bits %p\n", dibsec.dsBm.bmBits, bits);
 
     /* test the DIB memory */
@@ -530,12 +530,12 @@ static void test_dibsections(void)
 
     hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIBSection\n");
     ok(dibsec.dsBmih.biClrUsed == 2,
         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
 
-    /* Test if the old BITMAPCOREINFO structure is supported */    
-        
+    /* Test if the old BITMAPCOREINFO structure is supported */
+
     pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
     pbci->bmciHeader.bcBitCount = 0;
 
@@ -626,7 +626,7 @@ static void test_dibsections(void)
     }
     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 16,
        "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 16);
     test_dib_info(hdib, bits, &pbmi->bmiHeader);
@@ -644,7 +644,7 @@ static void test_dibsections(void)
     }
     hdib = CreateDIBSection(hdcmem, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 256,
         "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
 
@@ -678,7 +678,7 @@ static void test_dibsections(void)
     oldpal = SelectPalette(hdc, hpal, TRUE);
     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 2, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 2);
 
     /* The colour table has already been grabbed from the dc, so we select back the
@@ -767,7 +767,7 @@ static void test_dibsections(void)
     oldpal = SelectPalette(hdc, hpal, TRUE);
     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
 
     test_dib_info(hdib, bits, &pbmi->bmiHeader);
@@ -805,7 +805,7 @@ static void test_dibsections(void)
     pbmi->bmiHeader.biClrUsed = 142;
     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 256, "created DIBSection: wrong biClrUsed field: %u, should be: %u\n", dibsec.dsBmih.biClrUsed, 256);
 
     test_dib_info(hdib, bits, &pbmi->bmiHeader);
@@ -863,7 +863,7 @@ static void test_dibsections(void)
     pbmi->bmiHeader.biClrUsed = 37;
     hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
     ok(hdib != NULL, "CreateDIBSection failed\n");
-    ok(GetObject(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
+    ok(GetObjectW(hdib, sizeof(DIBSECTION), &dibsec) != 0, "GetObject failed for DIB Section\n");
     ok(dibsec.dsBmih.biClrUsed == 0, "created DIBSection: wrong biClrUsed field: %u\n", dibsec.dsBmih.biClrUsed);
     oldbm = SelectObject(hdcmem, hdib);
     ret = GetDIBColorTable(hdcmem, 0, 256, rgb);
@@ -1209,6 +1209,49 @@ static void test_dib_formats(void)
     ret = GetDIBits(hdc, hbmp, 0, 0, NULL, bi, DIB_PAL_COLORS+2);
     ok( !ret, "GetDIBits succeeded with DIB_PAL_COLORS+2\n" );
 
+    bi->bmiHeader.biWidth = 0x4000;
+    bi->bmiHeader.biHeight = 0x4000;
+    bi->bmiHeader.biBitCount = 1;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib != NULL, "CreateDIBSection failed with large size\n" );
+    DeleteObject( hdib );
+
+    bi->bmiHeader.biWidth = 0x8001;
+    bi->bmiHeader.biHeight = 0x8001;
+    bi->bmiHeader.biBitCount = 32;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
+
+    bi->bmiHeader.biWidth = 1;
+    bi->bmiHeader.biHeight = 0x40000001;
+    bi->bmiHeader.biBitCount = 32;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
+
+    bi->bmiHeader.biWidth = 2;
+    bi->bmiHeader.biHeight = 0x40000001;
+    bi->bmiHeader.biBitCount = 16;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
+
+    bi->bmiHeader.biWidth = 0x40000001;
+    bi->bmiHeader.biHeight = 1;
+    bi->bmiHeader.biBitCount = 32;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
+
+    bi->bmiHeader.biWidth = 0x40000001;
+    bi->bmiHeader.biHeight = 4;
+    bi->bmiHeader.biBitCount = 8;
+    bi->bmiHeader.biCompression = BI_RGB;
+    hdib = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
+    ok( hdib == NULL, "CreateDIBSection succeeded with size overflow\n" );
+
     DeleteDC( memdc );
     DeleteObject( hbmp );
     ReleaseDC( 0, hdc );
@@ -1305,7 +1348,7 @@ static void test_mono_dibsection(void)
     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
     ok(ds_bits[0] == 0xaa, "out_bits %02x\n", ds_bits[0]);
 
-    /* SetDIBitsToDevice with a inverted bmi -> normal dib section */
+    /* SetDIBitsToDevice with an inverted bmi -> normal dib section */
 
     colors[0].rgbRed = 0xff;
     colors[0].rgbGreen = 0xff;
@@ -1390,7 +1433,7 @@ static void test_mono_dibsection(void)
     SetDIBitsToDevice(memdc, 0, 0, 10, 10, 0, 0, 0, 10, bits, pbmi, DIB_RGB_COLORS);
     ok(ds_bits[0] == 0x55, "out_bits %02x\n", ds_bits[0]);
 
-    /* SetDIBitsToDevice with a inverted bmi -> inverted dib section */
+    /* SetDIBitsToDevice with an inverted bmi -> inverted dib section */
 
     colors[0].rgbRed = 0xff;
     colors[0].rgbGreen = 0xff;
@@ -1455,7 +1498,7 @@ static void test_bitmap(void)
     hbmp = CreateBitmap(15, 15, 1, 1, NULL);
     assert(hbmp != NULL);
 
-    ret = GetObject(hbmp, sizeof(bm), &bm);
+    ret = GetObjectW(hbmp, sizeof(bm), &bm);
     ok(ret == sizeof(bm), "wrong size %d\n", ret);
 
     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
@@ -1482,7 +1525,7 @@ static void test_bitmap(void)
 
     hbmp_old = SelectObject(hdc, hbmp);
 
-    ret = GetObject(hbmp, sizeof(bm), &bm);
+    ret = GetObjectW(hbmp, sizeof(bm), &bm);
     ok(ret == sizeof(bm), "wrong size %d\n", ret);
 
     ok(bm.bmType == 0, "wrong bm.bmType %d\n", bm.bmType);
@@ -1502,16 +1545,16 @@ static void test_bitmap(void)
     ok(hbmp_old == hbmp, "wrong old bitmap %p\n", hbmp_old);
 
     /* test various buffer sizes for GetObject */
-    ret = GetObject(hbmp, sizeof(*bma) * 2, bma);
+    ret = GetObjectW(hbmp, sizeof(*bma) * 2, bma);
     ok(ret == sizeof(*bma), "wrong size %d\n", ret);
 
-    ret = GetObject(hbmp, sizeof(bm) / 2, &bm);
+    ret = GetObjectW(hbmp, sizeof(bm) / 2, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbmp, 0, &bm);
+    ret = GetObjectW(hbmp, 0, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
-    ret = GetObject(hbmp, 1, &bm);
+    ret = GetObjectW(hbmp, 1, &bm);
     ok(ret == 0, "%d != 0\n", ret);
 
     DeleteObject(hbmp);
@@ -1523,7 +1566,7 @@ 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 )
+static BOOL 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;
@@ -1532,8 +1575,9 @@ static int is_black_pen( COLORREF fg, COLORREF bg, int r, int g, int b )
 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;
+    char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors ) + 256 * sizeof(RGBQUAD)];
+    BITMAPINFO *info = (BITMAPINFO *)buffer;
+    RGBQUAD *colors = info->bmiColors;
     WORD bits[16];
     void *bits_ptr;
     COLORREF res;
@@ -1569,7 +1613,7 @@ static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g,
     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,
+    ok( bits[0] == 0x5555 || broken(bits[0] == 0xaada) /* XP SP1 & 2003 SP0 */,
         "wrong bits %04x for %02x,%02x,%02x fg %06x bg %06x\n", bits[0], r, g, b, fg, bg );
     DeleteObject( SelectObject( hdc, old_brush ));
 
@@ -1588,8 +1632,7 @@ static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g,
         "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;
+    memset( buffer, 0, sizeof(buffer) );
     info->bmiHeader.biSize = sizeof(info->bmiHeader);
     info->bmiHeader.biHeight = -16;
     info->bmiHeader.biWidth = 16;
@@ -1639,7 +1682,6 @@ static void test_bitmap_colors( HDC hdc, COLORREF fg, COLORREF bg, int r, int g,
         "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)
@@ -1691,6 +1733,7 @@ static void test_mono_bitmap(void)
             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)
@@ -1712,7 +1755,7 @@ static void test_bmBits(void)
     ok(hbmp != NULL, "CreateBitmap failed\n");
 
     memset(&bmp, 0xFF, sizeof(bmp));
-    ok(GetObject(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
+    ok(GetObjectW(hbmp, sizeof(bmp), &bmp) == sizeof(bmp),
        "GetObject failed or returned a wrong structure size\n");
     ok(!bmp.bmBits, "bmBits must be NULL for device-dependent bitmaps\n");
 
@@ -2048,7 +2091,7 @@ static void test_GetDIBits(void)
     ok(hbmp != 0, "CreateBitmap failed\n");
 
     memset(&bm, 0xAA, sizeof(bm));
-    bytes = GetObject(hbmp, sizeof(bm), &bm);
+    bytes = GetObjectW(hbmp, sizeof(bm), &bm);
     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
@@ -2164,7 +2207,7 @@ static void test_GetDIBits(void)
        lines, bm.bmHeight, GetLastError());
 
     memset(&bm, 0xAA, sizeof(bm));
-    bytes = GetObject(hbmp, sizeof(bm), &bm);
+    bytes = GetObjectW(hbmp, sizeof(bm), &bm);
     ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
     ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
     ok(bm.bmWidth == 16, "wrong bmWidth %d\n", bm.bmWidth);
@@ -2640,7 +2683,7 @@ static void test_select_object(void)
         }
 
         memset(&bm, 0xAA, sizeof(bm));
-        bytes = GetObject(hbm, sizeof(bm), &bm);
+        bytes = GetObjectW(hbm, sizeof(bm), &bm);
         ok(bytes == sizeof(bm), "GetObject returned %d\n", bytes);
         ok(bm.bmType == 0, "wrong bmType %d\n", bm.bmType);
         ok(bm.bmWidth == 10, "wrong bmWidth %d\n", bm.bmWidth);
@@ -2668,12 +2711,12 @@ static void test_mono_1x1_bmp_dbg(HBITMAP hbmp, int line)
     ret = GetObjectType(hbmp);
     ok_(__FILE__, line)(ret == OBJ_BITMAP, "the object %p is not bitmap\n", hbmp);
 
-    ret = GetObject(hbmp, 0, 0);
+    ret = GetObjectW(hbmp, 0, 0);
     ok_(__FILE__, line)(ret == sizeof(BITMAP), "object size %d\n", ret);
 
     memset(&bm, 0xDA, sizeof(bm));
     SetLastError(0xdeadbeef);
-    ret = GetObject(hbmp, sizeof(bm), &bm);
+    ret = GetObjectW(hbmp, sizeof(bm), &bm);
     if (!ret) /* XP, only for curObj2 */ return;
     ok_(__FILE__, line)(ret == sizeof(BITMAP), "GetObject returned %d, error %u\n", ret, GetLastError());
     ok_(__FILE__, line)(bm.bmType == 0, "wrong bmType, expected 0 got %d\n", bm.bmType);
@@ -2770,7 +2813,7 @@ todo_wine
             continue;
         }
         ok(bm != 0, "CreateBitmapIndirect error %u\n", GetLastError());
-        GetObject(bm, sizeof(bmp), &bmp);
+        GetObjectW(bm, sizeof(bmp), &bmp);
         if(i == 1) {
             expect = 1;
         } else if(i <= 4) {
@@ -5585,7 +5628,7 @@ START_TEST(bitmap)
 {
     HMODULE hdll;
 
-    hdll = GetModuleHandle("gdi32.dll");
+    hdll = GetModuleHandleA("gdi32.dll");
     pGdiAlphaBlend   = (void*)GetProcAddress(hdll, "GdiAlphaBlend");
     pGdiGradientFill = (void*)GetProcAddress(hdll, "GdiGradientFill");
     pSetLayout       = (void*)GetProcAddress(hdll, "SetLayout");
index 76e158d..9026a4a 100755 (executable)
@@ -49,7 +49,7 @@ static void test_solidbrush(void)
 
     for(i=0; i<sizeof(stock)/sizeof(stock[0]); i++) {
         solidBrush = CreateSolidBrush(stock[i].color);
-        
+
         if(stock[i].stockobj != -1) {
             stockBrush = GetStockObject(stock[i].stockobj);
             ok(stockBrush!=solidBrush ||
@@ -59,20 +59,20 @@ static void test_solidbrush(void)
         else
             stockBrush = NULL;
         memset(&br, 0, sizeof(br));
-        ret = GetObject(solidBrush, sizeof(br), &br);
+        ret = GetObjectW(solidBrush, sizeof(br), &br);
         ok( ret !=0, "GetObject on solid %s brush failed, error=%d\n", stock[i].name, GetLastError());
         ok(br.lbStyle==BS_SOLID, "%s brush has wrong style, got %d expected %d\n", stock[i].name, br.lbStyle, BS_SOLID);
         ok(br.lbColor==stock[i].color, "%s brush has wrong color, got 0x%08x expected 0x%08x\n", stock[i].name, br.lbColor, stock[i].color);
-        
+
         if(stockBrush) {
             /* Sanity check, make sure the colors being compared do in fact have a stock brush */
-            ret = GetObject(stockBrush, sizeof(br), &br);
+            ret = GetObjectW(stockBrush, sizeof(br), &br);
             ok( ret !=0, "GetObject on stock %s brush failed, error=%d\n", stock[i].name, GetLastError());
             ok(br.lbColor==stock[i].color, "stock %s brush unexpected color, got 0x%08x expected 0x%08x\n", stock[i].name, br.lbColor, stock[i].color);
         }
 
         DeleteObject(solidBrush);
-        ret = GetObject(solidBrush, sizeof(br), &br);
+        ret = GetObjectW(solidBrush, sizeof(br), &br);
         ok(ret==0 ||
            broken(ret!=0), /* win9x */
            "GetObject succeeded on a deleted %s brush\n", stock[i].name);
@@ -92,7 +92,7 @@ static void test_hatch_brush(void)
         if (i < HS_API_MAX)
         {
             ok( brush != 0, "%u: CreateHatchBrush failed err %u\n", i, GetLastError() );
-            size = GetObject( brush, sizeof(lb), &lb );
+            size = GetObjectW( brush, sizeof(lb), &lb );
             ok( size == sizeof(lb), "wrong size %u\n", size );
             ok( lb.lbColor == RGB(12,34,56), "wrong color %08x\n", lb.lbColor );
             if (i <= HS_DIAGCROSS)
index 0247bbb..e90f2f4 100644 (file)
@@ -2,6 +2,7 @@
  * Unit test suite for clipping
  *
  * Copyright 2005 Huw Davies
+ * Copyright 2008,2011,2013 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -388,6 +389,12 @@ static void test_memory_dc_clipping(void)
     ret = GetClipRgn(hdc, hrgn);
     ok(ret == 0, "expected 0, got %d\n", ret);
 
+    ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
+    ret = GetClipRgn(hdc, hrgn);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
     SelectObject(hdc, hbmp);
 
     ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
@@ -409,6 +416,17 @@ static void test_memory_dc_clipping(void)
     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_DIFF);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
+    ret = GetClipRgn(hdc, hrgn);
+    ok(ret == 1, "expected 1, got %d\n", ret);
+
+    ret = GetRgnBox(hrgn, &rc);
+    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
+    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);
+
     DeleteDC(hdc);
     DeleteObject(hrgn);
     DeleteObject(hrgn_empty);
@@ -420,7 +438,7 @@ static void test_window_dc_clipping(void)
     HDC hdc;
     HRGN hrgn, hrgn_empty;
     HWND hwnd;
-    RECT rc;
+    RECT rc, virtual_rect;
     int ret, screen_width, screen_height;
 
     /* Windows versions earlier than Win2k do not support the virtual screen metrics,
@@ -429,6 +447,8 @@ static void test_window_dc_clipping(void)
     if(!screen_width) screen_width = GetSystemMetrics(SM_CXSCREEN);
     screen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
     if(!screen_height) screen_height = GetSystemMetrics(SM_CYSCREEN);
+    SetRect(&virtual_rect, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN),
+            GetSystemMetrics(SM_XVIRTUALSCREEN) + screen_width, GetSystemMetrics(SM_YVIRTUALSCREEN) + screen_height);
 
     trace("screen resolution %d x %d\n", screen_width, screen_height);
 
@@ -441,6 +461,12 @@ static void test_window_dc_clipping(void)
     ret = GetClipRgn(hdc, hrgn);
     ok(ret == 0, "expected 0, got %d\n", ret);
 
+    ret = ExtSelectClipRgn(hdc, 0, RGN_DIFF);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
+    ret = GetClipRgn(hdc, hrgn);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
     ret = ExtSelectClipRgn(hdc, hrgn_empty, RGN_DIFF);
     ok(ret == SIMPLEREGION || (ret == COMPLEXREGION && GetSystemMetrics(SM_CMONITORS) > 1),
        "expected SIMPLEREGION, got %d\n", ret);
@@ -450,9 +476,9 @@ static void test_window_dc_clipping(void)
 
     ret = GetRgnBox(hrgn, &rc);
     ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
-    ok(rc.left == 0 && rc.top == 0 && rc.right == screen_width && rc.bottom == screen_height,
-       "expected 0,0-%d,%d, got %d,%d-%d,%d\n", screen_width, screen_height,
-        rc.left, rc.top, rc.right, rc.bottom);
+    ok(EqualRect(&rc, &virtual_rect), "expected %d,%d-%d,%d, got %d,%d-%d,%d\n",
+       virtual_rect.left, virtual_rect.top, virtual_rect.right, virtual_rect.bottom,
+       rc.left, rc.top, rc.right, rc.bottom);
 
     SetRect( &rc, 10, 10, 20, 20 );
     ret = RectVisible( hdc, &rc );
@@ -462,6 +488,18 @@ static void test_window_dc_clipping(void)
     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_DIFF);
+    ok(ret == 0, "expected 0, got %d\n", ret);
+
+    ret = GetClipRgn(hdc, hrgn);
+    ok(ret == 1, "expected 1, got %d\n", ret);
+
+    ret = GetRgnBox(hrgn, &rc);
+    ok(ret == SIMPLEREGION, "expected SIMPLEREGION, got %d\n", ret);
+    ok(EqualRect(&rc, &virtual_rect), "expected %d,%d-%d,%d, got %d,%d-%d,%d\n",
+       virtual_rect.left, virtual_rect.top, virtual_rect.right, virtual_rect.bottom,
+       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);
index 5f19370..d215d9c 100644 (file)
@@ -457,12 +457,46 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
     type = GetClipBox( ref_dc, &rect );
     if (type != COMPLEXREGION && type != ERROR)  /* region can be complex on multi-monitor setups */
     {
+        RECT ref_rect;
+
         ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
-        ok( rect.left == 0 && rect.top == 0 &&
-            rect.right == GetDeviceCaps( ref_dc, DESKTOPHORZRES ) &&
-            rect.bottom == GetDeviceCaps( ref_dc, DESKTOPVERTRES ),
-            "GetClipBox returned %d,%d,%d,%d on %s\n",
-            rect.left, rect.top, rect.right, rect.bottom, descr );
+        if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
+        {
+            if (GetSystemMetrics( SM_CXSCREEN ) != GetSystemMetrics( SM_CXVIRTUALSCREEN ))
+                todo_wine ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
+                              "Got DESKTOPHORZRES %d on %s, expected %d\n",
+                              GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
+            else
+                ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
+                    "Got DESKTOPHORZRES %d on %s, expected %d\n",
+                    GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
+
+            if (GetSystemMetrics( SM_CYSCREEN ) != GetSystemMetrics( SM_CYVIRTUALSCREEN ))
+                todo_wine ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
+                              "Got DESKTOPVERTRES %d on %s, expected %d\n",
+                              GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
+            else
+                ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
+                    "Got DESKTOPVERTRES %d on %s, expected %d\n",
+                    GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
+
+            SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
+                     GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
+                     GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
+        }
+        else
+        {
+            SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
+                     GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
+        }
+
+        if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY && GetObjectType( hdc ) != OBJ_ENHMETADC &&
+            (GetSystemMetrics( SM_XVIRTUALSCREEN ) || GetSystemMetrics( SM_YVIRTUALSCREEN )))
+            todo_wine ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %d,%d,%d,%d on %s\n",
+                          rect.left, rect.top, rect.right, rect.bottom, descr );
+        else
+            ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %d,%d,%d,%d on %s\n",
+                rect.left, rect.top, rect.right, rect.bottom, descr );
     }
 
     SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
@@ -531,19 +565,19 @@ static void test_CreateCompatibleDC(void)
     HDC hdc, hNewDC, hdcMetafile, screen_dc;
     HBITMAP bitmap;
     INT caps;
-    DEVMODE dm;
+    DEVMODEA dm;
 
     bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
 
-    bRet = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm);
+    bRet = EnumDisplaySettingsA(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 );
+    hdc = CreateDCA( "DISPLAY", NULL, NULL, &dm );
 
-    screen_dc = CreateDC( "DISPLAY", NULL, NULL, NULL );
+    screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
     test_device_caps( hdc, screen_dc, "display dc", 1 );
-    ResetDC( hdc, &dm );
+    ResetDCA( hdc, &dm );
     test_device_caps( hdc, screen_dc, "display dc", 1 );
     DeleteDC( hdc );
 
@@ -573,7 +607,7 @@ static void test_CreateCompatibleDC(void)
     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
     ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
     test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
-    ResetDC( hdcMetafile, &dm );
+    ResetDCA( hdcMetafile, &dm );
     test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
     DeleteDC( hNewDC );
     DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
@@ -586,7 +620,7 @@ static void test_CreateCompatibleDC(void)
     caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
     ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
     test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
-    ResetDC( hdcMetafile, &dm );
+    ResetDCA( hdcMetafile, &dm );
     test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
     DeleteMetaFile( CloseMetaFile( hdcMetafile ));
 
@@ -673,7 +707,7 @@ static void test_DeleteDC(void)
 {
     HWND hwnd;
     HDC hdc, hdc_test;
-    WNDCLASSEX cls;
+    WNDCLASSEXA cls;
     int ret;
 
     /* window DC */
@@ -727,7 +761,7 @@ static void test_DeleteDC(void)
     memset(&cls, 0, sizeof(cls));
     cls.cbSize = sizeof(cls);
     cls.style = CS_CLASSDC;
-    cls.hInstance = GetModuleHandle(0);
+    cls.hInstance = GetModuleHandleA(NULL);
     cls.lpszClassName = "Wine class DC";
     cls.lpfnWndProc = DefWindowProcA;
     ret = RegisterClassExA(&cls);
@@ -766,7 +800,7 @@ static void test_DeleteDC(void)
     ret = GetObjectType(hdc_test);
     ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
 
-    ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
+    ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
     ok(ret, "UnregisterClassA failed\n");
 
     ret = GetObjectType(hdc_test);
@@ -777,7 +811,7 @@ todo_wine
     memset(&cls, 0, sizeof(cls));
     cls.cbSize = sizeof(cls);
     cls.style = CS_OWNDC;
-    cls.hInstance = GetModuleHandle(0);
+    cls.hInstance = GetModuleHandleA(NULL);
     cls.lpszClassName = "Wine own DC";
     cls.lpfnWndProc = DefWindowProcA;
     ret = RegisterClassExA(&cls);
@@ -811,7 +845,7 @@ todo_wine
 
     DestroyWindow(hwnd);
 
-    ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
+    ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
     ok(ret, "UnregisterClassA failed\n");
 }
 
@@ -1262,7 +1296,7 @@ static HDC create_printer_dc(int scale, BOOL reset)
            dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName,
            is_postscript_printer(hdc) ? "" : "NOT " );
 
-    if (reset) ResetDC( hdc, pbuf->pDevMode );
+    if (reset) ResetDCA( hdc, pbuf->pDevMode );
 done:
     HeapFree( GetProcessHeap(), 0, dbuf );
     HeapFree( GetProcessHeap(), 0, pbuf );
@@ -1346,7 +1380,7 @@ static void test_printer_dc(void)
 
 START_TEST(dc)
 {
-    pSetLayout = (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
+    pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
     test_dc_values();
     test_savedc();
     test_savedc_2();
index 9a11405..6b2b9be 100644 (file)
@@ -136,8 +136,8 @@ static const char *sha1_graphics_a8r8g8b8[] =
     "d7dd4700f49808541bba99244b7eb5840e0a2439",
     "af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
     "568f87f0194ca19b69a5b2bcdef795d89c5721ce",
-    "50d19fe68b2ab4fdbb5d590cdca6dc84a95bab68",
-    "a1fde1094d2c19ddb20871842dae1da73618709e",
+    "a37810f46dee8741fe5adbb3f1f2e87012ffc929",
+    "50a09678c49c208f71d40452daca5411279aa674",
     "e462052a03dbe4ec3814db7700e166d00d4d686f",
     "a27917d4db49ce77989fae246015aeb2a28520ee",
     "657514a4ca1f2b6ca7a125ad58dfed82099a37d1",
@@ -209,8 +209,8 @@ static const char *sha1_graphics_a8r8g8b8_bitfields[] =
     "d7dd4700f49808541bba99244b7eb5840e0a2439",
     "af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
     "568f87f0194ca19b69a5b2bcdef795d89c5721ce",
-    "50d19fe68b2ab4fdbb5d590cdca6dc84a95bab68",
-    "a1fde1094d2c19ddb20871842dae1da73618709e",
+    "a37810f46dee8741fe5adbb3f1f2e87012ffc929",
+    "50a09678c49c208f71d40452daca5411279aa674",
     "0cda6b3297003b3ccd6d5baa17e1ca9bb7c56f08",
     "b2c8e1ebb9435031fe068442f479d1304096e79f",
     "657514a4ca1f2b6ca7a125ad58dfed82099a37d1",
@@ -282,8 +282,8 @@ static const char *sha1_graphics_a8b8g8r8[] =
     "86c84cc8306975edecc6d4a89a8aff29f59b55a7",
     "af99228aa4cfbd1f61bd824db046144a3c6c2ed7",
     "25675c30adfe24d6cae60793b156dfdaa36ac3ba",
-    "1cb1810b127f509117b38d62a15b67b2347b9145",
-    "f05b3294f25de5fa6d1114104bca97871052ea5a",
+    "849d4abf4b690128a5f70e9b8ac78f20c437de06",
+    "e768fc9f3167ef3144a4cfb1e20126a577f7dd5b",
     "87f57a31253a38dbf3dc3070473328fa04b68a48",
     "db64cc4d830fc35ed170b53943e722b2342954d4",
     "9988ceca44dafbee247aece1f027c06c27c01652",
@@ -355,8 +355,8 @@ static const char *sha1_graphics_r10g10b10[] =
     "fc0c32afb719295f28bcfef22803bef94f798e20",
     "36f6db4fbe2a1630a7597d3a446f2902755c96ef",
     "d3f08946300e1700865042aed121870e292d1095",
-    "467ff4af1e105855874f27fbf84d1d2b0417ab5d",
-    "fb0dcff8a67a88313557ee8b588aaa2004fe7b8b",
+    "4782df8e24127e66a434b4e839adebf2dbb223fb",
+    "739707cc85ca63e0580c79618dc0bb8a4a338d95",
     "8ea5d7e4bebc40a1d91b04b12e1c11a42c188095",
     "317521e576801acaea62c76fe16813cdfe20f4ad",
     "ce0fc29bb0281d6c955d64e239254ef9e6dbc06d",
@@ -428,8 +428,8 @@ static const char *sha1_graphics_r6g6b6[] =
     "49341c297a887186bd47d7465d827ab3147f05e3",
     "325279e76367200d3fd7194d81c09fd139988ece",
     "c3def160a1e847605ff0fc7edd30397fa90635a0",
-    "a9c2158329c207638cfd2c82cd8a6218efdb28d2",
-    "7f0c4e6874f0c36cee64ff5dec76258ca8822cb2",
+    "2b3e87e0b705b03c7c08f403409ab82cce095ba1",
+    "45c08e11fffc78b2a3574263419e0cb7f8cd9b45",
     "aecb242c31f31a90f071b6455ea7d808d4ea22e3",
     "77ea86e51a94b11a8081b29696cb4115687843e3",
     "d67b897cad72d31e75359094007b1346fd8806ea",
@@ -501,8 +501,8 @@ static const char *sha1_graphics_24[] =
     "b25ba91487ec945410deb2b51bc1156890c032a8",
     "d347ca5c6c4b6a61389247c3b6f61564033e8c25",
     "ee315634ed92da3a32c2675ecd1b369471c60936",
-    "6776e0612410e7e200c853721b4ab6ad8b6b81f5",
-    "620a5a520d81971a2d9c30b8d836ba696e11b8dd",
+    "099c688a920f606655b485e8f0a433dc811bc976",
+    "9c044a733335bca43766bda2b317249309155079",
     "354b92008a8409c62d0fa1dff1532c5943aa37a2",
     "8dc9cb7deae5c24d1eae004d53893fa6caf4723c",
     "cf311a96d41bd98fdbdfb5dfaac4ba1ba9b7d6da",
@@ -578,8 +578,8 @@ static const char *sha1_graphics_r5g5b5[] =
     "3772003c7fb420003512d0c437b3659d96d89ce4",
     "dab47c9dc149e570045d699598b14a613bf319b3",
     "2daca4d26a086ed34894693be0b0374402232809",
-    "e313ae8f7261b88999757ed0c6f26df85b4f01a5",
-    "47d0bab8664ae0aaa927495d07bb3537cce35f16",
+    "904f1d82159bcf5485f323bd12b859dc5e83f8eb",
+    "5bd29f94844351e9a5bd01f25d85608b9b0701b2",
     "295ec16530126046790fb734e99f86f5b3b74ed8",
     "d98b0561010606b55a1b9b85fbc93640f681d256",
     "1c1499051860b7caa25173b328ca9c862f01dd1a",
@@ -650,8 +650,8 @@ static const char *sha1_graphics_r4g4b4[] =
     "f0acb3cfcda62e95bee5f7bc8830ffeb3dd7e5a7",
     "07b10c3f191d0a93e5e5694aae37dcad407e10f5",
     "f7900e60347029876ba55e8f0c4c02e89deb36b6",
-    "7d80b8289da8a65931f03c74a9ef0aff5f8eb551",
-    "a7a986097e5b553c71bd93fd0ec6037e6bd0f2d1",
+    "f373a5f37b82e7523c64c08eb509b6191e49b173",
+    "9f0760a05190c9edf9ce2e8be6aaa5557601fe91",
     "7587a9c87cab1eca827807f351bb67ca184d1ac5",
     "b53ef0b5c674822e784903a9dbdd3b386d9f2350",
     "5505d2ed20dc61ffe48832ecf5329162a5ceb734",
@@ -728,8 +728,8 @@ static const char *sha1_graphics_8_color[] =
     "9ae38bb94c7b4c0c6dfebbee23d1de4db9b77488",
     "678979a45126a76eb629992cd64734862f53a555",
     "2f7ba8803604c032cb1a1228bc021f0f1c03e245",
-    "9b1cc7b24f8ce15db2af7f4aa8cde8687784dfa2",
-    "cc4a4cea622d825700bccef7d90a5a447d9ca39d",
+    "52e7c2f8b01592898c13f1e7633881e350244209",
+    "d9d5556b77301952b4caf113337720966bc8e1f5",
     "e58d9c0acf0219d0839e1dbd162e08a765ed7f0f",
     "34ca0f9660e1889f9f2c0deb80535d3c4f349fa4",
     "2c07272462c68cf5944b03e2aa049475b99143c5",
@@ -810,9 +810,9 @@ static const char *sha1_graphics_8_grayscale[] =
     "fb63bbb2f944fb63ed2d7399f07b168740c1034b",
     "3685c9ae95118a83db3569832c29753276fa1264",
     "09640bad951c33e7d70a1fced83b1869f65b3fc5",
-    "cb9ea8137eca1450e049879772f5c11a0e11ff0a",
-    "a4b04ed35484de0de61832a8a28bbc7def645622",
-    "515897610714251dd3b54f54fe76a9ed3fd12c53",
+    "5eb00252664ec39e61359adb1dade4906a87a248",
+    "ee7b9b292ea9fb559ef5ebf6a2a5586d38c7f854",
+    "dcad1a146c1d0ec2c4cc7f64bd4f45c57a604bfe",
     "0ca8775d9a61ccc251d1e6f2e3cfd26a24ae24a2",
     "17ae603c199a5d6695d198a7f36e6d7263990951",
     "1918a33f59d3500204ffc573318a39e9ff754221",
@@ -887,8 +887,8 @@ static const char *sha1_graphics_8[] =
     "31e667c2dbb81dcf81d01cb88f794e88ddb90ff2",
     "465d9cd0a77ab4fcf035aa67544b2a26269e0b09",
     "600d6b2713d5e4c0d90c02660245ed26c7ae3033",
-    "d4f3a5ea033adc405c44e1ca137dc908c606dad6",
-    "7103d428ec9a959778120fd6f0dc62dd608ddd63",
+    "0025a440866a404523a8a20e79a8891e45a2ff56",
+    "c04d335933895f836f0a28c1e3f7f444352c3b8e",
     "bd28d77cd85b20a2384d6b25082cfd884bba683e",
     "7e591ec8ae9bb61c3a443c93f071cab2b8978394",
     "f81c70b6ee2d4690f9f7c797c66582b176f8dcef",
@@ -959,8 +959,8 @@ static const char *sha1_graphics_4[] =
     "df5feb905a31c288008cf5e82d73ac818a160d82",
     "d8af3868c66c7d6dac35ec8ee0317b38a6910bb1",
     "ec8e2aebfb4a1c28ebcd0e053b9e4d8638b50951",
-    "1a23839d71d2379ed4e709a5ae6c14639fbe3ab8",
-    "09f8416a780d80be61cbda3d8a05aee418d0ea00",
+    "ccf8d11b1e81895e9781f17c227c821228d8714b",
+    "f751e26578193afe6a727ee2a52318c404c56555",
     "28a6b9f7927e99e53cf46f0333d29168cb10e920",
     "029552113292cc110fd6b7888e766628950aaeef",
     "297f6ad15200bffbf15198324ee8f27a61a6f2d4",
@@ -1031,8 +1031,8 @@ static const char *sha1_graphics_4_grayscale[] =
     "f8681c09f1abfc38d31e47622cb8798cd896a00e",
     "b5ee51cfc73acb59a2f6124509ea236f8fc7f9f7",
     "d374d4d92c940ae42a9b42c14d744341b68a8c14",
-    "43560b856907f552df3b9dd1f91e1aa8ab9ff17e",
-    "8cefa6dcb658487d0715598d5d120677dbfdab42",
+    "06a6a224be0f5cdc51ac4704f9f57fc1f3813d6f",
+    "c47c2dc806b6b8ff28f300949695d013a46c0083",
     "ada3b7c34946e584dcdf4203e07cfa3dad02bc63",
     "c2f61571b067a44b30f56b4658c9606f0edfc0f3",
     "58f400c9bb78e49a879276fb049edfc9c981740a",
@@ -1052,14 +1052,14 @@ static const char *sha1_graphics_4_grayscale[] =
 static const char *sha1_graphics_1[] =
 {
     "23366004515f3bc46796ea505d748f8d0f97fbe1",
-    "ad674a4104c6a1eacaee8f20effdfe31775b4409",
-    "a7cc69f957d7b533a0a330859a143d701daac73c",
-    "a955bf088c5edb129289ce65caace48ec95632e4",
-    "5316d3c558c254479883133cf58cd07ab521d3f0",
-    "fcbfdb5d60716ea05f2d1896fae7a6e7a8249d35",
-    "2c140b39cc8d21358fded8959cd655f03d7f0f89",
-    "121423a38b4ac4743bd516e0a7e88a3863796313",
-    "7c17635c6c7f62dbf8fd4773d0c503358553d2c7",
+    "61ade9054d4477fb89cf830539a5e8b4e45f0688",
+    "ac530c5dbaf837e15b2337347e974184fad73643",
+    "95fdcda26262d5948a9ade77d83fd698e0031050",
+    "1dd5cee06af78d026e5da8bfe3f45e1cf51faa13",
+    "f6b61ecf03ad11752775faca1d4404c6bb5065f5",
+    "d7ad44d6f377598268e9968333ae2cf23a0715ca",
+    "5871339cd7e6cee12d4dc45934a89071c73efe6b",
+    "69e9b85b34caf736069ba91e57a5c3fa7c891653",
     "21d5d9e47bb07de2cf7bc99b7725390d03a6cde6",
     "f69ee65ea25676429a28eea79b5b9cb9206b8d01",
     "39ff81f77ef4ee772367ed1a63785987c060126e",
@@ -1122,7 +1122,7 @@ static const char *sha1_graphics_1[] =
     "88763f8e8fcf4f78fa864325791a9dd35a0bd279",
     "013cee26bac8f815eadad4bfc012d9b5d01c3b7f",
     "44a28536466dc895feb824b23dfd4a47c6948af8",
-    "f0316a5765a0404760e94cd05b7dc956cae07d26",
+    "17468a3789f0a6d65c302bda735a01dc2c1a74d9",
     "781d8c5cbc28591fd48fce06f984c502fdc6b363",
     "df510792a7790cc699532b1420d43c6d4da2ae2f",
     "55c26d22f11d80b73383fa57d0fac552d705b092",
@@ -1131,14 +1131,14 @@ static const char *sha1_graphics_1[] =
     "4842a30dd7fdf38ddc3ddec85c08efe13a0e2e0b",
     "cc76db6da5ba1776f20240a5ad97a26a9cdf96b0",
     "014f477664a7f4ce4a948d6359a2707119afc8e2",
-    "1ee4e951743efc8764249fbc7adecefbfec0428e",
+    "74d01690e344bc22e7a0478e7a09ccd92354c486",
     "9ab50a663b74577b656e9849484a909d7ac52eeb",
     "128eefd2ee043d59dc37918065f687e378e5ca95",
-    "c642abc651f525332d9d635049646d309e877839",
+    "d7e2daab98ce1f698c4bfedfc01c0d79fcb76b8e",
     "8d34215487088b5d4ef63062270ce25c2862643d",
-    "3dc3075b0c87fdcaabbbae8928303fb2358c15c2",
+    "826562eb11a0d0bba77fa21245f7406a194e9225",
     "bbae6f0659e095a42b420082079663f937065813",
-    "ca711c69165e1fa5be72993b9a7870ef6d485249",
+    "bbabe686a6955402c90530e7c67f1428868369b3",
     NULL
 };
 
@@ -1488,6 +1488,129 @@ static const DWORD four_by_four_data[16] = { 0x000000, 0xff0000, 0x00ff00, 0x000
 static const DWORD ddb_brush_bits[8] = { 0x11112222, 0x33334444, 0x55556666, 0x77778888,
                                          0xaaaaaaaa, 0x00000000, 0x98765432, 0xabcdef00 };
 
+static const RGBQUAD default_palette_1[2] =
+{
+    { 0x00, 0x00, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+static const RGBQUAD default_palette_4[16] =
+{
+    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x80 },
+    { 0xc0, 0xc0, 0xc0 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff },
+};
+
+static const RGBQUAD default_palette_8[256] =
+{
+    { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x80 }, { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x80 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x80 }, { 0x80, 0x80, 0x00 }, { 0xc0, 0xc0, 0xc0 },
+    { 0xc0, 0xdc, 0xc0 }, { 0xf0, 0xca, 0xa6 }, { 0x00, 0x20, 0x40 }, { 0x00, 0x20, 0x60 },
+    { 0x00, 0x20, 0x80 }, { 0x00, 0x20, 0xa0 }, { 0x00, 0x20, 0xc0 }, { 0x00, 0x20, 0xe0 },
+    { 0x00, 0x40, 0x00 }, { 0x00, 0x40, 0x20 }, { 0x00, 0x40, 0x40 }, { 0x00, 0x40, 0x60 },
+    { 0x00, 0x40, 0x80 }, { 0x00, 0x40, 0xa0 }, { 0x00, 0x40, 0xc0 }, { 0x00, 0x40, 0xe0 },
+    { 0x00, 0x60, 0x00 }, { 0x00, 0x60, 0x20 }, { 0x00, 0x60, 0x40 }, { 0x00, 0x60, 0x60 },
+    { 0x00, 0x60, 0x80 }, { 0x00, 0x60, 0xa0 }, { 0x00, 0x60, 0xc0 }, { 0x00, 0x60, 0xe0 },
+    { 0x00, 0x80, 0x00 }, { 0x00, 0x80, 0x20 }, { 0x00, 0x80, 0x40 }, { 0x00, 0x80, 0x60 },
+    { 0x00, 0x80, 0x80 }, { 0x00, 0x80, 0xa0 }, { 0x00, 0x80, 0xc0 }, { 0x00, 0x80, 0xe0 },
+    { 0x00, 0xa0, 0x00 }, { 0x00, 0xa0, 0x20 }, { 0x00, 0xa0, 0x40 }, { 0x00, 0xa0, 0x60 },
+    { 0x00, 0xa0, 0x80 }, { 0x00, 0xa0, 0xa0 }, { 0x00, 0xa0, 0xc0 }, { 0x00, 0xa0, 0xe0 },
+    { 0x00, 0xc0, 0x00 }, { 0x00, 0xc0, 0x20 }, { 0x00, 0xc0, 0x40 }, { 0x00, 0xc0, 0x60 },
+    { 0x00, 0xc0, 0x80 }, { 0x00, 0xc0, 0xa0 }, { 0x00, 0xc0, 0xc0 }, { 0x00, 0xc0, 0xe0 },
+    { 0x00, 0xe0, 0x00 }, { 0x00, 0xe0, 0x20 }, { 0x00, 0xe0, 0x40 }, { 0x00, 0xe0, 0x60 },
+    { 0x00, 0xe0, 0x80 }, { 0x00, 0xe0, 0xa0 }, { 0x00, 0xe0, 0xc0 }, { 0x00, 0xe0, 0xe0 },
+    { 0x40, 0x00, 0x00 }, { 0x40, 0x00, 0x20 }, { 0x40, 0x00, 0x40 }, { 0x40, 0x00, 0x60 },
+    { 0x40, 0x00, 0x80 }, { 0x40, 0x00, 0xa0 }, { 0x40, 0x00, 0xc0 }, { 0x40, 0x00, 0xe0 },
+    { 0x40, 0x20, 0x00 }, { 0x40, 0x20, 0x20 }, { 0x40, 0x20, 0x40 }, { 0x40, 0x20, 0x60 },
+    { 0x40, 0x20, 0x80 }, { 0x40, 0x20, 0xa0 }, { 0x40, 0x20, 0xc0 }, { 0x40, 0x20, 0xe0 },
+    { 0x40, 0x40, 0x00 }, { 0x40, 0x40, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x40, 0x40, 0x60 },
+    { 0x40, 0x40, 0x80 }, { 0x40, 0x40, 0xa0 }, { 0x40, 0x40, 0xc0 }, { 0x40, 0x40, 0xe0 },
+    { 0x40, 0x60, 0x00 }, { 0x40, 0x60, 0x20 }, { 0x40, 0x60, 0x40 }, { 0x40, 0x60, 0x60 },
+    { 0x40, 0x60, 0x80 }, { 0x40, 0x60, 0xa0 }, { 0x40, 0x60, 0xc0 }, { 0x40, 0x60, 0xe0 },
+    { 0x40, 0x80, 0x00 }, { 0x40, 0x80, 0x20 }, { 0x40, 0x80, 0x40 }, { 0x40, 0x80, 0x60 },
+    { 0x40, 0x80, 0x80 }, { 0x40, 0x80, 0xa0 }, { 0x40, 0x80, 0xc0 }, { 0x40, 0x80, 0xe0 },
+    { 0x40, 0xa0, 0x00 }, { 0x40, 0xa0, 0x20 }, { 0x40, 0xa0, 0x40 }, { 0x40, 0xa0, 0x60 },
+    { 0x40, 0xa0, 0x80 }, { 0x40, 0xa0, 0xa0 }, { 0x40, 0xa0, 0xc0 }, { 0x40, 0xa0, 0xe0 },
+    { 0x40, 0xc0, 0x00 }, { 0x40, 0xc0, 0x20 }, { 0x40, 0xc0, 0x40 }, { 0x40, 0xc0, 0x60 },
+    { 0x40, 0xc0, 0x80 }, { 0x40, 0xc0, 0xa0 }, { 0x40, 0xc0, 0xc0 }, { 0x40, 0xc0, 0xe0 },
+    { 0x40, 0xe0, 0x00 }, { 0x40, 0xe0, 0x20 }, { 0x40, 0xe0, 0x40 }, { 0x40, 0xe0, 0x60 },
+    { 0x40, 0xe0, 0x80 }, { 0x40, 0xe0, 0xa0 }, { 0x40, 0xe0, 0xc0 }, { 0x40, 0xe0, 0xe0 },
+    { 0x80, 0x00, 0x00 }, { 0x80, 0x00, 0x20 }, { 0x80, 0x00, 0x40 }, { 0x80, 0x00, 0x60 },
+    { 0x80, 0x00, 0x80 }, { 0x80, 0x00, 0xa0 }, { 0x80, 0x00, 0xc0 }, { 0x80, 0x00, 0xe0 },
+    { 0x80, 0x20, 0x00 }, { 0x80, 0x20, 0x20 }, { 0x80, 0x20, 0x40 }, { 0x80, 0x20, 0x60 },
+    { 0x80, 0x20, 0x80 }, { 0x80, 0x20, 0xa0 }, { 0x80, 0x20, 0xc0 }, { 0x80, 0x20, 0xe0 },
+    { 0x80, 0x40, 0x00 }, { 0x80, 0x40, 0x20 }, { 0x80, 0x40, 0x40 }, { 0x80, 0x40, 0x60 },
+    { 0x80, 0x40, 0x80 }, { 0x80, 0x40, 0xa0 }, { 0x80, 0x40, 0xc0 }, { 0x80, 0x40, 0xe0 },
+    { 0x80, 0x60, 0x00 }, { 0x80, 0x60, 0x20 }, { 0x80, 0x60, 0x40 }, { 0x80, 0x60, 0x60 },
+    { 0x80, 0x60, 0x80 }, { 0x80, 0x60, 0xa0 }, { 0x80, 0x60, 0xc0 }, { 0x80, 0x60, 0xe0 },
+    { 0x80, 0x80, 0x00 }, { 0x80, 0x80, 0x20 }, { 0x80, 0x80, 0x40 }, { 0x80, 0x80, 0x60 },
+    { 0x80, 0x80, 0x80 }, { 0x80, 0x80, 0xa0 }, { 0x80, 0x80, 0xc0 }, { 0x80, 0x80, 0xe0 },
+    { 0x80, 0xa0, 0x00 }, { 0x80, 0xa0, 0x20 }, { 0x80, 0xa0, 0x40 }, { 0x80, 0xa0, 0x60 },
+    { 0x80, 0xa0, 0x80 }, { 0x80, 0xa0, 0xa0 }, { 0x80, 0xa0, 0xc0 }, { 0x80, 0xa0, 0xe0 },
+    { 0x80, 0xc0, 0x00 }, { 0x80, 0xc0, 0x20 }, { 0x80, 0xc0, 0x40 }, { 0x80, 0xc0, 0x60 },
+    { 0x80, 0xc0, 0x80 }, { 0x80, 0xc0, 0xa0 }, { 0x80, 0xc0, 0xc0 }, { 0x80, 0xc0, 0xe0 },
+    { 0x80, 0xe0, 0x00 }, { 0x80, 0xe0, 0x20 }, { 0x80, 0xe0, 0x40 }, { 0x80, 0xe0, 0x60 },
+    { 0x80, 0xe0, 0x80 }, { 0x80, 0xe0, 0xa0 }, { 0x80, 0xe0, 0xc0 }, { 0x80, 0xe0, 0xe0 },
+    { 0xc0, 0x00, 0x00 }, { 0xc0, 0x00, 0x20 }, { 0xc0, 0x00, 0x40 }, { 0xc0, 0x00, 0x60 },
+    { 0xc0, 0x00, 0x80 }, { 0xc0, 0x00, 0xa0 }, { 0xc0, 0x00, 0xc0 }, { 0xc0, 0x00, 0xe0 },
+    { 0xc0, 0x20, 0x00 }, { 0xc0, 0x20, 0x20 }, { 0xc0, 0x20, 0x40 }, { 0xc0, 0x20, 0x60 },
+    { 0xc0, 0x20, 0x80 }, { 0xc0, 0x20, 0xa0 }, { 0xc0, 0x20, 0xc0 }, { 0xc0, 0x20, 0xe0 },
+    { 0xc0, 0x40, 0x00 }, { 0xc0, 0x40, 0x20 }, { 0xc0, 0x40, 0x40 }, { 0xc0, 0x40, 0x60 },
+    { 0xc0, 0x40, 0x80 }, { 0xc0, 0x40, 0xa0 }, { 0xc0, 0x40, 0xc0 }, { 0xc0, 0x40, 0xe0 },
+    { 0xc0, 0x60, 0x00 }, { 0xc0, 0x60, 0x20 }, { 0xc0, 0x60, 0x40 }, { 0xc0, 0x60, 0x60 },
+    { 0xc0, 0x60, 0x80 }, { 0xc0, 0x60, 0xa0 }, { 0xc0, 0x60, 0xc0 }, { 0xc0, 0x60, 0xe0 },
+    { 0xc0, 0x80, 0x00 }, { 0xc0, 0x80, 0x20 }, { 0xc0, 0x80, 0x40 }, { 0xc0, 0x80, 0x60 },
+    { 0xc0, 0x80, 0x80 }, { 0xc0, 0x80, 0xa0 }, { 0xc0, 0x80, 0xc0 }, { 0xc0, 0x80, 0xe0 },
+    { 0xc0, 0xa0, 0x00 }, { 0xc0, 0xa0, 0x20 }, { 0xc0, 0xa0, 0x40 }, { 0xc0, 0xa0, 0x60 },
+    { 0xc0, 0xa0, 0x80 }, { 0xc0, 0xa0, 0xa0 }, { 0xc0, 0xa0, 0xc0 }, { 0xc0, 0xa0, 0xe0 },
+    { 0xc0, 0xc0, 0x00 }, { 0xc0, 0xc0, 0x20 }, { 0xc0, 0xc0, 0x40 }, { 0xc0, 0xc0, 0x60 },
+    { 0xc0, 0xc0, 0x80 }, { 0xc0, 0xc0, 0xa0 }, { 0xf0, 0xfb, 0xff }, { 0xa4, 0xa0, 0xa0 },
+    { 0x80, 0x80, 0x80 }, { 0x00, 0x00, 0xff }, { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0xff },
+    { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0xff }, { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0xff }
+};
+
+static HPALETTE create_default_palette( int bpp )
+{
+    char pal_buffer[sizeof(LOGPALETTE) + 255 * sizeof(PALETTEENTRY)];
+    LOGPALETTE *pal = (LOGPALETTE *)pal_buffer;
+    PALETTEENTRY *entries = pal->palPalEntry;
+    int i;
+
+    pal->palVersion = 0x300;
+    pal->palNumEntries = 1 << bpp;
+    switch (bpp)
+    {
+    case 1:
+        for (i = 0; i < 2; i++)
+        {
+            entries[i].peRed   = default_palette_1[i].rgbRed;
+            entries[i].peGreen = default_palette_1[i].rgbGreen;
+            entries[i].peBlue  = default_palette_1[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    case 4:
+        for (i = 0; i < 16; i++)
+        {
+            entries[i].peRed   = default_palette_4[i].rgbRed;
+            entries[i].peGreen = default_palette_4[i].rgbGreen;
+            entries[i].peBlue  = default_palette_4[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    case 8:
+        for (i = 0; i < 256; i++)
+        {
+            entries[i].peRed   = default_palette_8[i].rgbRed;
+            entries[i].peGreen = default_palette_8[i].rgbGreen;
+            entries[i].peBlue  = default_palette_8[i].rgbBlue;
+            entries[i].peFlags = 0;
+        }
+        break;
+    }
+    return CreatePalette( pal );
+}
+
 static inline void solid_patblt( HDC hdc, int x, int y, int width, int height, COLORREF color )
 {
     HBRUSH brush = CreateSolidBrush( color );
@@ -1518,7 +1641,7 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits)
     BOOL dib_is_8bpp_gray = (bmi->bmiHeader.biBitCount == 8 && bmi->bmiColors[1].rgbRed == 1);
     BLENDFUNCTION blend;
     COLORREF old_text, old_bkgnd;
-    HPALETTE hpal;
+    HPALETTE hpal, old_hpal;
 
     blend.BlendOp = AC_SRC_OVER;
     blend.BlendFlags = 0;
@@ -2605,7 +2728,7 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits)
         entries[i].peFlags = 0;
     }
     hpal = CreatePalette( pal );
-    SelectPalette( hdc, hpal, FALSE );
+    old_hpal = SelectPalette( hdc, hpal, FALSE );
 
     solid_patblt( hdc, 20, 10, 10, 10, PALETTEINDEX(15) );
     Rectangle( hdc, 0, 0, 10, 10 );
@@ -2632,7 +2755,7 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits)
     SelectObject( hdc, orig_brush );
     DeleteObject( dib_brush );
 
-    SelectPalette( hdc, GetStockObject(DEFAULT_PALETTE), FALSE );
+    SelectPalette( hdc, old_hpal, FALSE );
     DeleteObject( hpal );
 
     /* NT4 broken for all cases, W2K for 1 bpp only */
@@ -2655,7 +2778,7 @@ static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits)
     SelectObject( hdc, solid_brush );
 
     ret = ExtFloodFill( hdc, 100, 100, RGB( 0, 0xff, 0 ), FLOODFILLSURFACE );
-    ok (!ret == !!dib_is_1bpp, "got ret %d\n", ret);
+    ok (ret, "got ret %d\n", ret);
     compare_hash(hdc, bmi, bits, "flood fill" );
 
     ExtSelectClipRgn( hdc, NULL, RGN_COPY );
@@ -2724,17 +2847,17 @@ static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
 static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
 {
     DWORD dib_size = get_dib_size(bmi), ret;
-    LOGFONT lf;
+    LOGFONTA lf;
     HFONT font;
     GLYPHMETRICS gm;
     BYTE g_buf[10000];
     int i, stride, x, y;
     static const MAT2 identity = { {0,1}, {0,0}, {0,0}, {0,1} };
     char *eto_hash = NULL, *diy_hash = NULL;
-    static const char *str = "Hello Wine";
+    static const char str[] = "Hello Wine";
     POINT origin, g_org;
     static const BYTE vals[4] = { 0x00, 0x00, 0x00, 0x00 };
-    TEXTMETRIC tm;
+    TEXTMETRICA tm;
     COLORREF text_color;
 
     for(i = 0; i < dib_size; i++)
@@ -2745,10 +2868,10 @@ static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
     lf.lfHeight = 24;
     lf.lfQuality = aa ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY;
 
-    font = CreateFontIndirect( &lf );
+    font = CreateFontIndirectA( &lf );
     font = SelectObject( hdc, font );
 
-    GetTextMetrics( hdc, &tm );
+    GetTextMetricsA( hdc, &tm );
     if (!(tm.tmPitchAndFamily & TMPF_VECTOR))
     {
         skip( "skipping as a bitmap font has been selected for Tahoma.\n" );
@@ -2762,7 +2885,7 @@ static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
     origin.x = 10;
     origin.y = 100;
 
-    ExtTextOut( hdc, origin.x, origin.y, 0, NULL, str, strlen(str), NULL );
+    ExtTextOutA( hdc, origin.x, origin.y, 0, NULL, str, strlen(str), NULL );
     eto_hash = hash_dib( bmi, bits );
 
     for(i = 0; i < dib_size; i++)
@@ -2775,11 +2898,11 @@ static void draw_text_2( HDC hdc, BITMAPINFO *bmi, BYTE *bits, BOOL aa )
     {
         DWORD ggo_flags = aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
 
-        ret = GetGlyphOutline( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
+        ret = GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
 
         if (ret == GDI_ERROR) continue;
 
-        if (ret) GetGlyphOutline( hdc, str[i], ggo_flags, &gm, sizeof(g_buf), g_buf, &identity );
+        if (ret) GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, sizeof(g_buf), g_buf, &identity );
 
         g_org.x = origin.x + gm.gmptGlyphOrigin.x;
         g_org.y = origin.y - gm.gmptGlyphOrigin.y;
@@ -2859,6 +2982,7 @@ static void test_simple_graphics(void)
     BYTE *bits;
     HBITMAP dib, orig_bm;
     DIBSECTION ds;
+    HPALETTE default_palette, old_hpal;
     int i;
 
     mem_dc = CreateCompatibleDC(NULL);
@@ -2885,6 +3009,9 @@ static void test_simple_graphics(void)
 
     orig_bm = SelectObject(mem_dc, dib);
 
+    default_palette = create_default_palette( 8 );
+    old_hpal = SelectPalette( mem_dc, default_palette, FALSE );
+
     dst_format = "8888";
     current_sha1 = sha1_graphics_a8r8g8b8;
     draw_graphics(mem_dc, bmi, bits);
@@ -2910,6 +3037,7 @@ static void test_simple_graphics(void)
     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
 
     orig_bm = SelectObject(mem_dc, dib);
+    SelectPalette( mem_dc, default_palette, FALSE );
 
     dst_format = "8888 - bitfields";
     current_sha1 = sha1_graphics_a8r8g8b8_bitfields;
@@ -3148,6 +3276,7 @@ static void test_simple_graphics(void)
     ok(dib != NULL, "ret NULL\n");
 
     orig_bm = SelectObject(mem_dc, dib);
+    DeleteObject( SelectPalette( mem_dc, create_default_palette(4), FALSE ));
 
     dst_format = "4";
     current_sha1 = sha1_graphics_4;
@@ -3191,12 +3320,14 @@ static void test_simple_graphics(void)
     ok(dib != NULL, "ret NULL\n");
 
     orig_bm = SelectObject(mem_dc, dib);
+    DeleteObject( SelectPalette( mem_dc, create_default_palette(1), FALSE ));
 
     dst_format = "1";
     current_sha1 = sha1_graphics_1;
     draw_graphics(mem_dc, bmi, bits);
     draw_text(mem_dc, bmi, bits);
 
+    DeleteObject( SelectPalette( mem_dc, old_hpal, FALSE ));
     SelectObject(mem_dc, orig_bm);
     DeleteObject(dib);
 
index 394ffb4..f0427c5 100644 (file)
@@ -31,7 +31,7 @@
 #include "wine/test.h"
 
 /* Do not allow more than 1 deviation here */
-#define match_off_by_1(a, b) (abs((a) - (b)) <= 1)
+#define match_off_by_1(a, b, exact) (abs((a) - (b)) <= ((exact) ? 0 : 1))
 
 #define near_match(a, b) (abs((a) - (b)) <= 6)
 #define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
@@ -42,13 +42,15 @@ static BOOL  (WINAPI *pGetCharABCWidthsI)(HDC hdc, UINT first, UINT count, LPWOR
 static BOOL  (WINAPI *pGetCharABCWidthsA)(HDC hdc, UINT first, UINT last, LPABC abc);
 static BOOL  (WINAPI *pGetCharABCWidthsW)(HDC hdc, UINT first, UINT last, LPABC abc);
 static BOOL  (WINAPI *pGetCharABCWidthsFloatW)(HDC hdc, UINT first, UINT last, LPABCFLOAT abc);
+static BOOL  (WINAPI *pGetCharWidth32A)(HDC hdc, UINT first, UINT last, LPINT buffer);
+static BOOL  (WINAPI *pGetCharWidth32W)(HDC hdc, UINT first, UINT last, LPINT buffer);
 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 HFONT (WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *);
 static HANDLE (WINAPI *pAddFontMemResourceEx)(PVOID, DWORD, PVOID, DWORD *);
 static BOOL  (WINAPI *pRemoveFontMemResourceEx)(HANDLE);
 static INT   (WINAPI *pAddFontResourceExA)(LPCSTR, DWORD, PVOID);
@@ -58,6 +60,21 @@ static HMODULE hgdi32 = 0;
 static const MAT2 mat = { {0,1}, {0,0}, {0,0}, {0,1} };
 static WORD system_lang_id;
 
+#ifdef WORDS_BIGENDIAN
+#define GET_BE_WORD(x) (x)
+#define GET_BE_DWORD(x) (x)
+#else
+#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
+#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
+#endif
+
+#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
+                    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
+                    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
+#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
+#define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
+#define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
+
 static void init(void)
 {
     hgdi32 = GetModuleHandleA("gdi32.dll");
@@ -68,6 +85,8 @@ static void init(void)
     pGetCharABCWidthsA = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsA");
     pGetCharABCWidthsW = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsW");
     pGetCharABCWidthsFloatW = (void *)GetProcAddress(hgdi32, "GetCharABCWidthsFloatW");
+    pGetCharWidth32A = (void *)GetProcAddress(hgdi32, "GetCharWidth32A");
+    pGetCharWidth32W = (void *)GetProcAddress(hgdi32, "GetCharWidth32W");
     pGetFontUnicodeRanges = (void *)GetProcAddress(hgdi32, "GetFontUnicodeRanges");
     pGetGlyphIndicesA = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesA");
     pGetGlyphIndicesW = (void *)GetProcAddress(hgdi32, "GetGlyphIndicesW");
@@ -82,7 +101,7 @@ static void init(void)
     system_lang_id = PRIMARYLANGID(GetSystemDefaultLangID());
 }
 
-static INT CALLBACK is_truetype_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK is_truetype_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     if (type != TRUETYPE_FONTTYPE) return 1;
 
@@ -101,7 +120,7 @@ static BOOL is_truetype_font_installed(const char *name)
     return ret;
 }
 
-static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK is_font_installed_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     return 0;
 }
@@ -118,6 +137,52 @@ static BOOL is_font_installed(const char *name)
     return ret;
 }
 
+static void *get_res_data(const char *fontname, DWORD *rsrc_size)
+{
+    HRSRC rsrc;
+    void *rsrc_data;
+
+    rsrc = FindResourceA(GetModuleHandleA(NULL), fontname, (LPCSTR)RT_RCDATA);
+    if (!rsrc) return NULL;
+
+    rsrc_data = LockResource(LoadResource(GetModuleHandleA(NULL), rsrc));
+    if (!rsrc_data) return NULL;
+
+    *rsrc_size = SizeofResource(GetModuleHandleA(NULL), rsrc);
+    if (!*rsrc_size) return NULL;
+
+    return rsrc_data;
+}
+
+static BOOL write_tmp_file( const void *data, DWORD *size, char *tmp_name )
+{
+    char tmp_path[MAX_PATH];
+    HANDLE hfile;
+    BOOL ret;
+
+    GetTempPathA(MAX_PATH, tmp_path);
+    GetTempFileNameA(tmp_path, "ttf", 0, tmp_name);
+
+    hfile = CreateFileA(tmp_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
+    if (hfile == INVALID_HANDLE_VALUE) return FALSE;
+
+    ret = WriteFile(hfile, data, *size, size, NULL);
+
+    CloseHandle(hfile);
+    return ret;
+}
+
+static BOOL write_ttf_file(const char *fontname, char *tmp_name)
+{
+    void *rsrc_data;
+    DWORD rsrc_size;
+
+    rsrc_data = get_res_data( fontname, &rsrc_size );
+    if (!rsrc_data) return FALSE;
+
+    return write_tmp_file( rsrc_data, &rsrc_size, tmp_name );
+}
+
 static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont)
 {
     LOGFONTA getobj_lf;
@@ -126,7 +191,7 @@ static void check_font(const char* test, const LOGFONTA* lf, HFONT hfont)
     if (!hfont)
         return;
 
-    ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf);
+    ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
     /* NT4 tries to be clever and only returns the minimum length */
     while (lf->lfFaceName[minlen] && minlen < LF_FACESIZE-1)
         minlen++;
@@ -196,11 +261,11 @@ static void test_logfont(void)
     DeleteObject(hfont);
 }
 
-static INT CALLBACK font_enum_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK font_enum_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     if (type & RASTER_FONTTYPE)
     {
-       LOGFONT *lf = (LOGFONT *)lParam;
+       LOGFONTA *lf = (LOGFONTA *)lParam;
        *lf = *elf;
        return 0; /* stop enumeration */
     }
@@ -239,7 +304,7 @@ static void test_font_metrics(HDC hdc, HFONT hfont, LONG lfHeight,
                              INT scale_x, INT scale_y)
 {
     LOGFONTA lf;
-    OUTLINETEXTMETRIC otm;
+    OUTLINETEXTMETRICA otm;
     TEXTMETRICA tm;
     SIZE size;
     INT width_of_A, cx, cy;
@@ -674,9 +739,9 @@ static void test_outline_font(void)
     DeleteDC(hdc);
 }
 
-static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK find_font_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
-    LOGFONT *lf = (LOGFONT *)lParam;
+    LOGFONTA *lf = (LOGFONTA *)lParam;
 
     if (elf->lfHeight == lf->lfHeight && !strcmp(elf->lfFaceName, lf->lfFaceName))
     {
@@ -847,9 +912,9 @@ static void test_bitmap_font_metrics(void)
     };
     static const int font_log_pixels[] = { 96, 120 };
     HDC hdc;
-    LOGFONT lf;
+    LOGFONTA lf;
     HFONT hfont, old_hfont;
-    TEXTMETRIC tm;
+    TEXTMETRICA tm;
     INT ret, i, expected_cs, screen_log_pixels, diff, font_res;
     char face_name[LF_FACESIZE];
     CHARSETINFO csi;
@@ -908,7 +973,7 @@ static void test_bitmap_font_metrics(void)
 
             lf.lfCharSet = csi.ciCharset;
             trace("looking for %s height %d charset %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet);
-            ret = EnumFontFamiliesEx(hdc, &lf, find_font_proc, (LPARAM)&lf, 0);
+            ret = EnumFontFamiliesExA(hdc, &lf, find_font_proc, (LPARAM)&lf, 0);
             if (fd[i].height & FH_SCALE)
                 ok(ret, "scaled font height %d should not be enumerated\n", height);
             else
@@ -928,10 +993,10 @@ static void test_bitmap_font_metrics(void)
             old_hfont = SelectObject(hdc, hfont);
 
             SetLastError(0xdeadbeef);
-            ret = GetTextFace(hdc, sizeof(face_name), face_name);
+            ret = GetTextFaceA(hdc, sizeof(face_name), face_name);
             ok(ret, "GetTextFace error %u\n", GetLastError());
 
-            if (lstrcmp(face_name, fd[i].face_name) != 0)
+            if (strcmp(face_name, fd[i].face_name) != 0)
             {
                 ok(ret != ANSI_CHARSET, "font charset should not be ANSI_CHARSET\n");
                 ok(ret != expected_cs, "font charset %d should not be %d\n", ret, expected_cs);
@@ -943,13 +1008,13 @@ static void test_bitmap_font_metrics(void)
 
             memset(&gm, 0, sizeof(gm));
             SetLastError(0xdeadbeef);
-            ret = GetGlyphOutline(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
+            ret = GetGlyphOutlineA(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);
+            bRet = GetTextMetricsA(hdc, &tm);
             ok(bRet, "GetTextMetrics error %d\n", GetLastError());
 
             SetLastError(0xdeadbeef);
@@ -988,7 +1053,7 @@ static void test_bitmap_font_metrics(void)
 
                     /* Don't run the max char width test on System/ANSI_CHARSET.  We have extra characters in our font
                        that make the max width bigger */
-                    if(strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET)
+                    if ((strcmp(lf.lfFaceName, "System") || lf.lfCharSet != ANSI_CHARSET) && tm.tmDigitizedAspectX == 96)
                         ok(tm.tmMaxCharWidth == fd[i].max_char_width, "%s(%d): tm.tmMaxCharWidth %d != %d\n", fd[i].face_name, height, tm.tmMaxCharWidth, fd[i].max_char_width);
                 }
                 else
@@ -1020,7 +1085,7 @@ static void test_GdiGetCharDimensions(void)
 
     hdc = CreateCompatibleDC(NULL);
 
-    GetTextExtentPoint(hdc, szAlphabet, strlen(szAlphabet), &size);
+    GetTextExtentPointA(hdc, szAlphabet, strlen(szAlphabet), &size);
     avgwidth = ((size.cx / 26) + 1) / 2;
 
     ret = pGdiGetCharDimensions(hdc, &tm, &height);
@@ -1041,15 +1106,15 @@ static void test_GdiGetCharDimensions(void)
     DeleteDC(hdc);
 }
 
-static int CALLBACK create_font_proc(const LOGFONT *lpelfe,
-                                     const TEXTMETRIC *lpntme,
+static int CALLBACK create_font_proc(const LOGFONTA *lpelfe,
+                                     const TEXTMETRICA *lpntme,
                                      DWORD FontType, LPARAM lParam)
 {
     if (FontType & TRUETYPE_FONTTYPE)
     {
         HFONT hfont;
 
-        hfont = CreateFontIndirect(lpelfe);
+        hfont = CreateFontIndirectA(lpelfe);
         if (hfont)
         {
             *(HFONT *)lParam = hfont;
@@ -1060,17 +1125,50 @@ static int CALLBACK create_font_proc(const LOGFONT *lpelfe,
     return 1;
 }
 
+static void ABCWidths_helper(const char* description, HDC hdc, WORD *glyphs, ABC *base_abci, ABC *base_abcw, ABCFLOAT *base_abcf, INT todo)
+{
+    ABC abc[1];
+    ABCFLOAT abcf[1];
+    BOOL ret = FALSE;
+
+    ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
+    ok(ret, "%s: GetCharABCWidthsI should have succeeded\n", description);
+    ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
+    if (todo) todo_wine ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    else ok(abc->abcA * base_abci->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    if (todo) todo_wine ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+    else ok(abc->abcC * base_abci->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+
+    ret = pGetCharABCWidthsW(hdc, 'i', 'i', abc);
+    ok(ret, "%s: GetCharABCWidthsW should have succeeded\n", description);
+    ok ((INT)abc->abcB > 0, "%s: abcB should be positive\n", description);
+    if (todo) todo_wine ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    else ok(abc->abcA * base_abcw->abcA >= 0, "%s: abcA's sign should be unchanged\n", description);
+    if (todo) todo_wine ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's sign should be unchanged\n", description);
+    else ok(abc->abcC * base_abcw->abcC >= 0, "%s: abcC's should be unchanged\n", description);
+
+    ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
+    ok(ret, "%s: GetCharABCWidthsFloatW should have succeeded\n", description);
+    ok (abcf->abcfB > 0.0, "%s: abcfB should be positive\n", description);
+    if (todo) todo_wine ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's sign should be unchanged\n", description);
+    else ok(abcf->abcfA * base_abcf->abcfA >= 0.0, "%s: abcfA's should be unchanged\n", description);
+    if (todo) todo_wine ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+    else ok(abcf->abcfC * base_abcf->abcfC >= 0.0, "%s: abcfC's sign should be unchanged\n", description);
+}
+
 static void test_GetCharABCWidths(void)
 {
-    static const WCHAR str[] = {'a',0};
+    static const WCHAR str[] = {'i',0};
     BOOL ret;
     HDC hdc;
     LOGFONTA lf;
     HFONT hfont;
     ABC abc[1];
+    ABC abcw[1];
     ABCFLOAT abcf[1];
     WORD glyphs[1];
     DWORD nb;
+    HWND hwnd;
     static const struct
     {
         UINT first;
@@ -1104,8 +1202,6 @@ static void test_GetCharABCWidths(void)
          {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
         {HANGEUL_CHARSET, 0x8141, 0xac02,
          {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
-        {JOHAB_CHARSET, 0x8446, 0x3135,
-         {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
         {GB2312_CHARSET, 0x8141, 0x4e04,
          {TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE}},
         {CHINESEBIG5_CHARSET, 0xa142, 0x3001,
@@ -1169,7 +1265,7 @@ static void test_GetCharABCWidths(void)
         lf.lfFaceName[0] = '\0';
         lf.lfCharSet = c[i].cs;
         lf.lfPitchAndFamily = 0;
-        if (EnumFontFamiliesEx(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
+        if (EnumFontFamiliesExA(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
         {
             skip("TrueType font for charset %u is not installed\n", c[i].cs);
             continue;
@@ -1212,14 +1308,108 @@ static void test_GetCharABCWidths(void)
         DeleteObject(hfont);
     }
 
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Tahoma");
+    lf.lfHeight = 200;
+    hfont = CreateFontIndirectA(&lf);
+
+    /* test empty glyph's metrics */
+    hfont = SelectObject(hdc, hfont);
+    ret = pGetCharABCWidthsFloatW(hdc, ' ', ' ', abcf);
+    ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
+    ok(abcf[0].abcfB == 1.0, "got %f\n", abcf[0].abcfB);
+    ret = pGetCharABCWidthsW(hdc, ' ', ' ', abcw);
+    ok(ret, "GetCharABCWidthsW should have succeeded\n");
+    ok(abcw[0].abcB == 1, "got %u\n", abcw[0].abcB);
+
+    /* 1) prepare unrotated font metrics */
+    ret = pGetCharABCWidthsW(hdc, 'a', 'a', abcw);
+    ok(ret, "GetCharABCWidthsW should have succeeded\n");
+    DeleteObject(SelectObject(hdc, hfont));
+
+    /* 2) get rotated font metrics */
+    lf.lfEscapement = lf.lfOrientation = 900;
+    hfont = CreateFontIndirectA(&lf);
+    hfont = SelectObject(hdc, hfont);
+    ret = pGetCharABCWidthsW(hdc, 'a', 'a', abc);
+    ok(ret, "GetCharABCWidthsW should have succeeded\n");
+
+    /* 3) compare ABC results */
+    ok(match_off_by_1(abcw[0].abcA, abc[0].abcA, FALSE),
+       "got %d, expected %d (A)\n", abc[0].abcA, abcw[0].abcA);
+    ok(match_off_by_1(abcw[0].abcB, abc[0].abcB, FALSE),
+       "got %d, expected %d (B)\n", abc[0].abcB, abcw[0].abcB);
+    ok(match_off_by_1(abcw[0].abcC, abc[0].abcC, FALSE),
+       "got %d, expected %d (C)\n", abc[0].abcC, abcw[0].abcC);
+
+    DeleteObject(SelectObject(hdc, hfont));
     ReleaseDC(NULL, hdc);
+
+    trace("ABC sign test for a variety of transforms:\n");
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Tahoma");
+    lf.lfHeight = 20;
+    hfont = CreateFontIndirectA(&lf);
+    hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
+                           0, 0, 0, NULL);
+    hdc = GetDC(hwnd);
+    SetMapMode(hdc, MM_ANISOTROPIC);
+    SelectObject(hdc, hfont);
+
+    nb = pGetGlyphIndicesW(hdc, str, 1, glyphs, 0);
+    ok(nb == 1, "GetGlyphIndicesW should have returned 1\n");
+
+    ret = pGetCharABCWidthsI(hdc, 0, 1, glyphs, abc);
+    ok(ret, "GetCharABCWidthsI should have succeeded\n");
+    ret = pGetCharABCWidthsW(hdc, 'i', 'i', abcw);
+    ok(ret, "GetCharABCWidthsW should have succeeded\n");
+    ret = pGetCharABCWidthsFloatW(hdc, 'i', 'i', abcf);
+    ok(ret, "GetCharABCWidthsFloatW should have succeeded\n");
+
+    ABCWidths_helper("LTR", hdc, glyphs, abc, abcw, abcf, 0);
+    SetWindowExtEx(hdc, -1, -1, NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ABCWidths_helper("LTR -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ABCWidths_helper("LTR -1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+    SetWindowExtEx(hdc, 1, 1, NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ABCWidths_helper("LTR 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ABCWidths_helper("LTR 1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
+
+    trace("RTL layout\n");
+    hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
+                           0, 0, 0, NULL);
+    hdc = GetDC(hwnd);
+    SetMapMode(hdc, MM_ANISOTROPIC);
+    SelectObject(hdc, hfont);
+
+    ABCWidths_helper("RTL", hdc, glyphs, abc, abcw, abcf, 0);
+    SetWindowExtEx(hdc, -1, -1, NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ABCWidths_helper("RTL -1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ABCWidths_helper("RTL -1 advanced", hdc, glyphs, abc, abcw, abcf, 0);
+    SetWindowExtEx(hdc, 1, 1, NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ABCWidths_helper("RTL 1 compatible", hdc, glyphs, abc, abcw, abcf, 0);
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ABCWidths_helper("RTL 1 advanced", hdc, glyphs, abc, abcw, abcf, 1);
+
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
+    DeleteObject(hfont);
 }
 
 static void test_text_extents(void)
 {
     static const WCHAR wt[] = {'O','n','e','\n','t','w','o',' ','3',0};
     LPINT extents;
-    INT i, len, fit1, fit2;
+    INT i, len, fit1, fit2, extents2[3];
     LOGFONTA lf;
     TEXTMETRICA tm;
     HDC hdc;
@@ -1281,7 +1471,6 @@ static void test_text_extents(void)
     GetTextExtentExPointW(hdc, wt, 2, 0, NULL, NULL, &sz1);
     ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy,
        "GetTextExtentExPointW with lpnFit and alpDx both NULL returns incorrect results\n");
-    HeapFree(GetProcessHeap(), 0, extents);
 
     /* extents functions fail with -ve counts (the interesting case being -1) */
     ret = GetTextExtentPointA(hdc, "o", -1, &sz);
@@ -1326,6 +1515,27 @@ static void test_text_extents(void)
 
     hfont = SelectObject(hdc, hfont);
     DeleteObject(hfont);
+
+    /* non-MM_TEXT mapping mode */
+    lf.lfHeight = 2000;
+    hfont = CreateFontIndirectA(&lf);
+    hfont = SelectObject(hdc, hfont);
+
+    SetMapMode( hdc, MM_HIMETRIC );
+    ret = GetTextExtentExPointW(hdc, wt, 3, 0, NULL, extents, &sz);
+    ok(ret, "got %d\n", ret);
+    ok(sz.cx == extents[2], "got %d vs %d\n", sz.cx, extents[2]);
+
+    ret = GetTextExtentExPointW(hdc, wt, 3, extents[1], &fit1, extents2, &sz2);
+    ok(ret, "got %d\n", ret);
+    ok(fit1 == 2, "got %d\n", fit1);
+    ok(sz2.cx == sz.cx, "got %d vs %d\n", sz2.cx, sz.cx);
+    for(i = 0; i < 2; i++)
+        ok(extents2[i] == extents[i], "%d: %d, %d\n", i, extents2[i], extents[i]);
+
+    hfont = SelectObject(hdc, hfont);
+    DeleteObject(hfont);
+    HeapFree(GetProcessHeap(), 0, extents);
     ReleaseDC(NULL, hdc);
 }
 
@@ -1338,7 +1548,7 @@ static void test_GetGlyphIndices(void)
     DWORD    flags = 0;
     WCHAR    testtext[] = {'T','e','s','t',0xffff,0};
     WORD     glyphs[(sizeof(testtext)/2)-1];
-    TEXTMETRIC textm;
+    TEXTMETRICA textm;
     HFONT hOldFont;
 
     if (!pGetGlyphIndicesW) {
@@ -1355,7 +1565,7 @@ static void test_GetGlyphIndices(void)
 
     hfont = CreateFontIndirectA(&lf);
     ok(hfont != 0, "CreateFontIndirectEx failed\n");
-    ok(GetTextMetrics(hdc, &textm), "GetTextMetric failed\n");
+    ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
     if (textm.tmCharSet == ANSI_CHARSET)
     {
         flags |= GGI_MARK_NONEXISTING_GLYPHS;
@@ -1383,7 +1593,7 @@ static void test_GetGlyphIndices(void)
 
     hfont = CreateFontIndirectA(&lf);
     hOldFont = SelectObject(hdc, hfont);
-    ok(GetTextMetrics(hdc, &textm), "GetTextMetric failed\n");
+    ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
     flags |= GGI_MARK_NONEXISTING_GLYPHS;
     charcount = pGetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
     ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %d\n", charcount);
@@ -1475,7 +1685,7 @@ static void test_GetKerningPairs(void)
         }
 #endif
     };
-    LOGFONT lf;
+    LOGFONTA lf;
     HFONT hfont, hfont_old;
     KERNINGPAIR *kern_pair;
     HDC hdc;
@@ -1511,7 +1721,7 @@ static void test_GetKerningPairs(void)
         memset(&lf, 0, sizeof(lf));
         strcpy(lf.lfFaceName, kd[i].face_name);
         lf.lfHeight = kd[i].height;
-        hfont = CreateFontIndirect(&lf);
+        hfont = CreateFontIndirectA(&lf);
         assert(hfont != 0);
 
         hfont_old = SelectObject(hdc, hfont);
@@ -1521,9 +1731,9 @@ static void test_GetKerningPairs(void)
         uiRet = GetOutlineTextMetricsW(hdc, sizeof(otm), &otm);
         ok(uiRet == sizeof(otm), "GetOutlineTextMetricsW error %d\n", GetLastError());
 
-        ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight), "expected %d, got %d\n",
+        ok(match_off_by_1(kd[i].tmHeight, otm.otmTextMetrics.tmHeight, FALSE), "expected %d, got %d\n",
            kd[i].tmHeight, otm.otmTextMetrics.tmHeight);
-        ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent), "expected %d, got %d\n",
+        ok(match_off_by_1(kd[i].tmAscent, otm.otmTextMetrics.tmAscent, FALSE), "expected %d, got %d\n",
            kd[i].tmAscent, otm.otmTextMetrics.tmAscent);
         ok(kd[i].tmDescent == otm.otmTextMetrics.tmDescent, "expected %d, got %d\n",
            kd[i].tmDescent, otm.otmTextMetrics.tmDescent);
@@ -1609,36 +1819,22 @@ todo_wine {
     ReleaseDC(0, hdc);
 }
 
-static void test_height_selection(void)
+struct font_data
 {
-    static const struct font_data
-    {
-        const char face_name[LF_FACESIZE];
-        int requested_height;
-        int weight, height, ascent, descent, int_leading, ext_leading, dpi;
-    } fd[] =
-    {
-        {"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96 },
-        {"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96 },
-        {"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96 },
-        {"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96 },
-        {"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96 },
-        {"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96 },
-        {"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96 },
-        {"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96 },
-        {"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96 },
-        {"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96 }
-    };
-    HDC hdc;
-    LOGFONT lf;
+    const char face_name[LF_FACESIZE];
+    int requested_height;
+    int weight, height, ascent, descent, int_leading, ext_leading, dpi;
+    BOOL exact;
+};
+
+static void test_height( HDC hdc, const struct font_data *fd )
+{
+    LOGFONTA lf;
     HFONT hfont, old_hfont;
-    TEXTMETRIC tm;
+    TEXTMETRICA tm;
     INT ret, i;
 
-    hdc = CreateCompatibleDC(0);
-    assert(hdc);
-
-    for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++)
+    for (i = 0; fd[i].face_name[0]; i++)
     {
         if (!is_truetype_font_installed(fd[i].face_name))
         {
@@ -1651,36 +1847,241 @@ static void test_height_selection(void)
         lf.lfWeight = fd[i].weight;
         strcpy(lf.lfFaceName, fd[i].face_name);
 
-        hfont = CreateFontIndirect(&lf);
+        hfont = CreateFontIndirectA(&lf);
         assert(hfont);
 
         old_hfont = SelectObject(hdc, hfont);
-        ret = GetTextMetrics(hdc, &tm);
+        ret = GetTextMetricsA(hdc, &tm);
         ok(ret, "GetTextMetrics error %d\n", GetLastError());
         if(fd[i].dpi == tm.tmDigitizedAspectX)
         {
             trace("found font %s, height %d charset %x dpi %d\n", lf.lfFaceName, lf.lfHeight, lf.lfCharSet, fd[i].dpi);
             ok(tm.tmWeight == fd[i].weight, "%s(%d): tm.tmWeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmWeight, fd[i].weight);
-            ok(match_off_by_1(tm.tmHeight, fd[i].height), "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
-            ok(match_off_by_1(tm.tmAscent, fd[i].ascent), "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
-            ok(match_off_by_1(tm.tmDescent, fd[i].descent), "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
-#if 0 /* FIXME: calculation of tmInternalLeading in Wine doesn't match what Windows does */
-            ok(tm.tmInternalLeading == fd[i].int_leading, "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
-#endif
+            ok(match_off_by_1(tm.tmHeight, fd[i].height, fd[i].exact), "%s(%d): tm.tmHeight %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmHeight, fd[i].height);
+            ok(match_off_by_1(tm.tmAscent, fd[i].ascent, fd[i].exact), "%s(%d): tm.tmAscent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmAscent, fd[i].ascent);
+            ok(match_off_by_1(tm.tmDescent, fd[i].descent, fd[i].exact), "%s(%d): tm.tmDescent %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmDescent, fd[i].descent);
+            ok(match_off_by_1(tm.tmInternalLeading, fd[i].int_leading, fd[i].exact), "%s(%d): tm.tmInternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmInternalLeading, fd[i].int_leading);
             ok(tm.tmExternalLeading == fd[i].ext_leading, "%s(%d): tm.tmExternalLeading %d != %d\n", fd[i].face_name, fd[i].requested_height, tm.tmExternalLeading, fd[i].ext_leading);
         }
 
         SelectObject(hdc, old_hfont);
         DeleteObject(hfont);
     }
+}
+
+static void *find_ttf_table( void *ttf, DWORD size, DWORD tag )
+{
+    WORD i, num_tables = GET_BE_WORD(*((WORD *)ttf + 2));
+    DWORD *table = (DWORD *)ttf + 3;
+
+    for (i = 0; i < num_tables; i++)
+    {
+        if (table[0] == tag)
+            return (BYTE *)ttf + GET_BE_DWORD(table[2]);
+        table += 4;
+    }
+    return NULL;
+}
+
+static void test_height_selection_vdmx( HDC hdc )
+{
+    static const struct font_data charset_0[] = /* doesn't use VDMX */
+    {
+        { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 14, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 15, FW_NORMAL, 15, 12, 3, 3, 0, 96, FALSE },
+        { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 17, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 18, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 19, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 20, FW_NORMAL, 20, 17, 3, 4, 0, 96, FALSE },
+        { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 5, 0, 96, FALSE },
+        { "wine_vdmx", 27, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", 28, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", 30, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", 31, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", 32, FW_NORMAL, 32, 27, 5, 6, 0, 96, FALSE },
+        { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
+        { "wine_vdmx", 64, FW_NORMAL, 64, 53, 11, 11, 0, 96, TRUE },
+        { "wine_vdmx", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
+        { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", -14, FW_NORMAL, 17, 14, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", -15, FW_NORMAL, 18, 15, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", -16, FW_NORMAL, 19, 16, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", -17, FW_NORMAL, 21, 17, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", -18, FW_NORMAL, 22, 18, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", -19, FW_NORMAL, 23, 19, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", -20, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", -21, FW_NORMAL, 25, 21, 4, 4, 0, 96, TRUE },
+        { "wine_vdmx", -22, FW_NORMAL, 27, 22, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", -23, FW_NORMAL, 28, 23, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", -25, FW_NORMAL, 30, 25, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", -26, FW_NORMAL, 31, 26, 5, 5, 0, 96, TRUE },
+        { "wine_vdmx", -27, FW_NORMAL, 33, 27, 6, 6, 0, 96, TRUE },
+        { "wine_vdmx", -28, FW_NORMAL, 34, 28, 6, 6, 0, 96, TRUE },
+        { "wine_vdmx", -29, FW_NORMAL, 35, 29, 6, 6, 0, 96, TRUE },
+        { "wine_vdmx", -30, FW_NORMAL, 36, 30, 6, 6, 0, 96, TRUE },
+        { "wine_vdmx", -31, FW_NORMAL, 37, 31, 6, 6, 0, 96, TRUE },
+        { "wine_vdmx", -32, FW_NORMAL, 39, 32, 7, 7, 0, 96, TRUE },
+        { "wine_vdmx", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
+        { "wine_vdmx", -64, FW_NORMAL, 77, 64, 13, 13, 0, 96, TRUE },
+        { "wine_vdmx", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
+        { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+    };
+
+    static const struct font_data charset_1[] = /* Uses VDMX */
+    {
+        { "wine_vdmx", 10, FW_NORMAL, 10, 8, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 11, FW_NORMAL, 11, 9, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 13, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 14, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 15, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", 16, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
+        { "wine_vdmx", 17, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 18, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", 19, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 20, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 21, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 22, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 23, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 24, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 25, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", 26, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", 27, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", 28, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", 29, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+        { "wine_vdmx", 30, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+        { "wine_vdmx", 31, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+        { "wine_vdmx", 32, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", 48, FW_NORMAL, 48, 40, 8, 10, 0, 96, TRUE },
+        { "wine_vdmx", 64, FW_NORMAL, 64, 54, 10, 13, 0, 96, TRUE },
+        { "wine_vdmx", 96, FW_NORMAL, 95, 79, 16, 18, 0, 96, TRUE },
+        { "wine_vdmx", -10, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", -11, FW_NORMAL, 13, 11, 2, 2, 0, 96, TRUE },
+        { "wine_vdmx", -12, FW_NORMAL, 16, 13, 3, 4, 0, 96, TRUE },
+        { "wine_vdmx", -13, FW_NORMAL, 16, 13, 3, 3, 0, 96, TRUE },
+        { "wine_vdmx", -14, FW_NORMAL, 19, 15, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -15, FW_NORMAL, 20, 16, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -16, FW_NORMAL, 21, 17, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -17, FW_NORMAL, 22, 18, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -18, FW_NORMAL, 23, 19, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -19, FW_NORMAL, 25, 21, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", -20, FW_NORMAL, 26, 22, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", -21, FW_NORMAL, 27, 23, 4, 6, 0, 96, TRUE },
+        { "wine_vdmx", -22, FW_NORMAL, 27, 23, 4, 5, 0, 96, TRUE },
+        { "wine_vdmx", -23, FW_NORMAL, 29, 24, 5, 6, 0, 96, TRUE },
+        { "wine_vdmx", -24, FW_NORMAL, 32, 26, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", -25, FW_NORMAL, 32, 26, 6, 7, 0, 96, TRUE },
+        { "wine_vdmx", -26, FW_NORMAL, 33, 27, 6, 7, 0, 96, TRUE },
+        { "wine_vdmx", -27, FW_NORMAL, 35, 29, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", -28, FW_NORMAL, 36, 30, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", -29, FW_NORMAL, 36, 30, 6, 7, 0, 96, TRUE },
+        { "wine_vdmx", -30, FW_NORMAL, 38, 32, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", -31, FW_NORMAL, 39, 33, 6, 8, 0, 96, TRUE },
+        { "wine_vdmx", -32, FW_NORMAL, 40, 33, 7, 8, 0, 96, TRUE },
+        { "wine_vdmx", -48, FW_NORMAL, 60, 50, 10, 12, 0, 96, TRUE },
+        { "wine_vdmx", -64, FW_NORMAL, 81, 67, 14, 17, 0, 96, TRUE },
+        { "wine_vdmx", -96, FW_NORMAL, 119, 99, 20, 23, 0, 96, TRUE },
+        { "", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+    };
+
+    static const struct vdmx_data
+    {
+        WORD version;
+        BYTE bCharSet;
+        const struct font_data *fd;
+    } data[] =
+    {
+        { 0, 0, charset_0 },
+        { 0, 1, charset_1 },
+        { 1, 0, charset_0 },
+        { 1, 1, charset_1 }
+    };
+    int i;
+    DWORD size, num;
+    WORD *vdmx_header;
+    BYTE *ratio_rec;
+    char ttf_name[MAX_PATH];
+    void *res, *copy;
+
+    if (!pAddFontResourceExA)
+    {
+        win_skip("AddFontResourceExA unavailable\n");
+        return;
+    }
+
+    for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+    {
+        res = get_res_data( "wine_vdmx.ttf", &size );
+
+        copy = HeapAlloc( GetProcessHeap(), 0, size );
+        memcpy( copy, res, size );
+        vdmx_header = find_ttf_table( copy, size, MS_MAKE_TAG('V','D','M','X') );
+        vdmx_header[0] = GET_BE_WORD( data[i].version );
+        ok( GET_BE_WORD( vdmx_header[1] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[1] ) );
+        ok( GET_BE_WORD( vdmx_header[2] ) == 1, "got %04x\n", GET_BE_WORD( vdmx_header[2] ) );
+        ratio_rec = (BYTE *)&vdmx_header[3];
+        ratio_rec[0] = data[i].bCharSet;
+
+        write_tmp_file( copy, &size, ttf_name );
+        HeapFree( GetProcessHeap(), 0, copy );
+
+        ok( !is_truetype_font_installed("wine_vdmx"), "Already installed\n" );
+        num = pAddFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+        if (!num) win_skip("Unable to add ttf font resource\n");
+        else
+        {
+            ok( is_truetype_font_installed("wine_vdmx"), "Not installed\n" );
+            test_height( hdc, data[i].fd );
+            pRemoveFontResourceExA( ttf_name, FR_PRIVATE, 0 );
+        }
+        DeleteFileA( ttf_name );
+    }
+}
+
+static void test_height_selection(void)
+{
+    static const struct font_data tahoma[] =
+    {
+        {"Tahoma", -12, FW_NORMAL, 14, 12, 2, 2, 0, 96, TRUE },
+        {"Tahoma", -24, FW_NORMAL, 29, 24, 5, 5, 0, 96, TRUE },
+        {"Tahoma", -48, FW_NORMAL, 58, 48, 10, 10, 0, 96, TRUE },
+        {"Tahoma", -96, FW_NORMAL, 116, 96, 20, 20, 0, 96, TRUE },
+        {"Tahoma", -192, FW_NORMAL, 232, 192, 40, 40, 0, 96, TRUE },
+        {"Tahoma", 12, FW_NORMAL, 12, 10, 2, 2, 0, 96, TRUE },
+        {"Tahoma", 24, FW_NORMAL, 24, 20, 4, 4, 0, 96, TRUE },
+        {"Tahoma", 48, FW_NORMAL, 48, 40, 8, 8, 0, 96, TRUE },
+        {"Tahoma", 96, FW_NORMAL, 96, 80, 16, 17, 0, 96, FALSE },
+        {"Tahoma", 192, FW_NORMAL, 192, 159, 33, 33, 0, 96, TRUE },
+        {"", 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+    };
+    HDC hdc = CreateCompatibleDC(0);
+    assert(hdc);
+
+    test_height( hdc, tahoma );
+    test_height_selection_vdmx( hdc );
 
     DeleteDC(hdc);
 }
 
 static void test_GetOutlineTextMetrics(void)
 {
-    OUTLINETEXTMETRIC *otm;
-    LOGFONT lf;
+    OUTLINETEXTMETRICA *otm;
+    LOGFONTA lf;
     HFONT hfont, hfont_old;
     HDC hdc;
     DWORD ret, otm_size;
@@ -1700,11 +2101,11 @@ static void test_GetOutlineTextMetrics(void)
     lf.lfWeight = FW_NORMAL;
     lf.lfPitchAndFamily = DEFAULT_PITCH;
     lf.lfQuality = PROOF_QUALITY;
-    hfont = CreateFontIndirect(&lf);
+    hfont = CreateFontIndirectA(&lf);
     assert(hfont != 0);
 
     hfont_old = SelectObject(hdc, hfont);
-    otm_size = GetOutlineTextMetrics(hdc, 0, NULL);
+    otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
     trace("otm buffer size %u (0x%x)\n", otm_size, otm_size);
 
     otm = HeapAlloc(GetProcessHeap(), 0, otm_size);
@@ -1712,7 +2113,7 @@ static void test_GetOutlineTextMetrics(void)
     memset(otm, 0xAA, otm_size);
     SetLastError(0xdeadbeef);
     otm->otmSize = sizeof(*otm); /* just in case for Win9x compatibility */
-    ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+    ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
     ok(ret == 1 /* Win9x */ ||
        ret == otm->otmSize /* XP*/,
        "expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
@@ -1727,7 +2128,7 @@ static void test_GetOutlineTextMetrics(void)
     memset(otm, 0xAA, otm_size);
     SetLastError(0xdeadbeef);
     otm->otmSize = otm_size; /* just in case for Win9x compatibility */
-    ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+    ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
     ok(ret == 1 /* Win9x */ ||
        ret == otm->otmSize /* XP*/,
        "expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
@@ -1744,7 +2145,7 @@ static void test_GetOutlineTextMetrics(void)
     memset(&unset_ptr, 0xAA, sizeof(unset_ptr));
     SetLastError(0xdeadbeef);
     otm->otmSize = sizeof(*otm) - sizeof(LPSTR); /* just in case for Win9x compatibility */
-    ret = GetOutlineTextMetrics(hdc, otm->otmSize, otm);
+    ret = GetOutlineTextMetricsA(hdc, otm->otmSize, otm);
     ok(ret == 1 /* Win9x */ ||
        ret == otm->otmSize /* XP*/,
        "expected %u, got %u, error %d\n", otm->otmSize, ret, GetLastError());
@@ -1764,18 +2165,18 @@ static void test_GetOutlineTextMetrics(void)
     ReleaseDC(0, hdc);
 }
 
-static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
+static void testJustification(HDC hdc, PCSTR str, RECT *clientArea)
 {
     INT         y,
                 breakCount,
                 areaWidth = clientArea->right - clientArea->left,
                 nErrors = 0, e;
-    PSTR        pFirstChar, pLastChar;
+    const char *pFirstChar, *pLastChar;
     SIZE        size;
     TEXTMETRICA tm;
     struct err
     {
-        char *start;
+        const char *start;
         int  len;
         int  GetTextExtentExPointWWidth;
     } error[20];
@@ -1796,7 +2197,7 @@ static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
             while (*str != '\0' && *str++ != tm.tmBreakChar);
             breakCount++;
             SetTextJustification(hdc, 0, 0);
-            GetTextExtentPoint32(hdc, pFirstChar, str - pFirstChar - 1, &size);
+            GetTextExtentPoint32A(hdc, pFirstChar, str - pFirstChar - 1, &size);
         } while ((int) size.cx < areaWidth);
 
         /* ignore trailing break chars */
@@ -1810,13 +2211,13 @@ static void testJustification(HDC hdc, PSTR str, RECT *clientArea)
         if (*str == '\0' || breakCount <= 0) pLastChar = str;
 
         SetTextJustification(hdc, 0, 0);
-        GetTextExtentPoint32(hdc, pFirstChar, pLastChar - pFirstChar, &size);
+        GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
 
         /* do not justify the last extent */
         if (*str != '\0' && breakCount > 0)
         {
             SetTextJustification(hdc, areaWidth - size.cx, breakCount);
-            GetTextExtentPoint32(hdc, pFirstChar, pLastChar - pFirstChar, &size);
+            GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
             if (size.cx != areaWidth && nErrors < sizeof(error)/sizeof(error[0]) - 1)
             {
                 error[nErrors].start = pFirstChar;
@@ -1852,7 +2253,7 @@ static void test_SetTextJustification(void)
     SIZE size, expect;
     int i;
     WORD indices[2];
-    static char testText[] =
+    static const char testText[] =
             "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
             "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
             "enim ad minim veniam, quis nostrud exercitation ullamco laboris "
@@ -1865,6 +2266,12 @@ static void test_SetTextJustification(void)
     GetClientRect( hwnd, &clientArea );
     hdc = GetDC( hwnd );
 
+    if (!is_font_installed("Times New Roman"))
+    {
+        skip("Times New Roman is not installed\n");
+        return;
+    }
+
     memset(&lf, 0, sizeof lf);
     lf.lfCharSet = ANSI_CHARSET;
     lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
@@ -1881,26 +2288,26 @@ static void test_SetTextJustification(void)
     pGetGlyphIndicesA( hdc, "A ", 2, indices, 0 );
 
     SetTextJustification(hdc, 0, 0);
-    GetTextExtentPoint32(hdc, " ", 1, &expect);
-    GetTextExtentPoint32(hdc, "   ", 3, &size);
+    GetTextExtentPoint32A(hdc, " ", 1, &expect);
+    GetTextExtentPoint32A(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);
+    GetTextExtentPoint32A(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);
+    GetTextExtentPoint32A(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);
+    GetTextExtentPoint32A(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);
+    GetTextExtentPoint32A(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);
+    GetTextExtentPoint32A(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);
@@ -1914,11 +2321,11 @@ static void test_SetTextJustification(void)
     DPtoLP( hdc, (POINT *)&clientArea, 2 );
     testJustification(hdc, testText, &clientArea);
 
-    GetTextExtentPoint32(hdc, "A", 1, &expect);
+    GetTextExtentPoint32A(hdc, "A", 1, &expect);
     for (i = 0; i < 10; i++)
     {
         SetTextCharacterExtra(hdc, i);
-        GetTextExtentPoint32(hdc, "A", 1, &size);
+        GetTextExtentPoint32A(hdc, "A", 1, &size);
         ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
     }
     SetTextCharacterExtra(hdc, 0);
@@ -1936,11 +2343,11 @@ static void test_SetTextJustification(void)
     DPtoLP( hdc, (POINT *)&clientArea, 2 );
     testJustification(hdc, testText, &clientArea);
 
-    GetTextExtentPoint32(hdc, "A", 1, &expect);
+    GetTextExtentPoint32A(hdc, "A", 1, &expect);
     for (i = 0; i < 10; i++)
     {
         SetTextCharacterExtra(hdc, i);
-        GetTextExtentPoint32(hdc, "A", 1, &size);
+        GetTextExtentPoint32A(hdc, "A", 1, &size);
         ok( size.cx == expect.cx + i, "wrong size %d/%d+%d\n", size.cx, expect.cx, i );
     }
 
@@ -2130,7 +2537,7 @@ static void test_GdiGetCodePage(void)
         { 950, "PMingLiU", ANSI_CHARSET, 950},
     };
     HDC         hdc;
-    LOGFONT     lf;
+    LOGFONTA    lf;
     HFONT       hfont;
     UINT        charset, acp;
     DWORD       codepage;
@@ -2229,13 +2636,13 @@ static void test_GetFontUnicodeRanges(void)
 struct enum_font_data
 {
     int total;
-    LOGFONT lf[MAX_ENUM_FONTS];
+    LOGFONTA lf[MAX_ENUM_FONTS];
 };
 
 struct enum_fullname_data
 {
     int total;
-    ENUMLOGFONT elf[MAX_ENUM_FONTS];
+    ENUMLOGFONTA elf[MAX_ENUM_FONTS];
 };
 
 struct enum_font_dataW
@@ -2244,10 +2651,10 @@ struct enum_font_dataW
     LOGFONTW lf[MAX_ENUM_FONTS];
 };
 
-static INT CALLBACK arial_enum_proc(const LOGFONT *lf, const TEXTMETRIC *tm, DWORD type, LPARAM lParam)
+static INT CALLBACK arial_enum_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
 {
     struct enum_font_data *efd = (struct enum_font_data *)lParam;
-    const NEWTEXTMETRIC *ntm = (const NEWTEXTMETRIC *)tm;
+    const NEWTEXTMETRICA *ntm = (const NEWTEXTMETRICA *)tm;
 
     ok(lf->lfHeight == tm->tmHeight, "lfHeight %d != tmHeight %d\n", lf->lfHeight, tm->tmHeight);
     ok(lf->lfHeight > 0 && lf->lfHeight < 200, "enumerated font height %d\n", lf->lfHeight);
@@ -2348,7 +2755,7 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset)
 {
     struct enum_font_data efd;
     struct enum_font_dataW efdw;
-    LOGFONT lf;
+    LOGFONTA lf;
     HDC hdc;
     int i, ret, ansi_charset, symbol_charset, russian_charset;
 
@@ -2406,7 +2813,7 @@ static void test_EnumFontFamilies(const char *font_name, INT font_charset)
 
     efd.total = 0;
     SetLastError(0xdeadbeef);
-    ret = EnumFontFamilies(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
+    ret = EnumFontFamiliesA(hdc, font_name, arial_enum_proc, (LPARAM)&efd);
     ok(ret, "EnumFontFamilies error %u\n", GetLastError());
     get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
     trace("enumerated ansi %d, symbol %d, russian %d fonts for %s\n",
@@ -2426,16 +2833,16 @@ todo_wine
 }
 else
         ok(efd.lf[i].lfCharSet == font_charset, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
-        ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+        ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
            font_name, efd.lf[i].lfFaceName);
     }
 
     memset(&lf, 0, sizeof(lf));
     lf.lfCharSet = ANSI_CHARSET;
-    lstrcpy(lf.lfFaceName, font_name);
+    strcpy(lf.lfFaceName, font_name);
     efd.total = 0;
     SetLastError(0xdeadbeef);
-    ret = EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    ret = EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
     ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
     get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
     trace("enumerated ansi %d, symbol %d, russian %d fonts for %s ANSI_CHARSET\n",
@@ -2455,7 +2862,7 @@ else
         {
             ok(efd.lf[i].lfCharSet == ANSI_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
             if (*font_name)
-                ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+                ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
                    font_name, efd.lf[i].lfFaceName);
         }
     }
@@ -2463,10 +2870,10 @@ else
     /* DEFAULT_CHARSET should enumerate all available charsets */
     memset(&lf, 0, sizeof(lf));
     lf.lfCharSet = DEFAULT_CHARSET;
-    lstrcpy(lf.lfFaceName, font_name);
+    strcpy(lf.lfFaceName, font_name);
     efd.total = 0;
     SetLastError(0xdeadbeef);
-    EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
     ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
     get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
     trace("enumerated ansi %d, symbol %d, russian %d fonts for %s DEFAULT_CHARSET\n",
@@ -2476,7 +2883,7 @@ else
     for (i = 0; i < efd.total; i++)
     {
         if (*font_name)
-            ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+            ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
                font_name, efd.lf[i].lfFaceName);
     }
     if (*font_name)
@@ -2521,10 +2928,10 @@ else
 
     memset(&lf, 0, sizeof(lf));
     lf.lfCharSet = SYMBOL_CHARSET;
-    lstrcpy(lf.lfFaceName, font_name);
+    strcpy(lf.lfFaceName, font_name);
     efd.total = 0;
     SetLastError(0xdeadbeef);
-    EnumFontFamiliesEx(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
+    EnumFontFamiliesExA(hdc, &lf, arial_enum_proc, (LPARAM)&efd, 0);
     ok(ret, "EnumFontFamiliesEx error %u\n", GetLastError());
     get_charset_stats(&efd, &ansi_charset, &symbol_charset, &russian_charset);
     trace("enumerated ansi %d, symbol %d, russian %d fonts for %s SYMBOL_CHARSET\n",
@@ -2539,7 +2946,7 @@ else
         {
             ok(efd.lf[i].lfCharSet == SYMBOL_CHARSET, "%d: got charset %d\n", i, efd.lf[i].lfCharSet);
             if (*font_name)
-                ok(!lstrcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
+                ok(!strcmp(efd.lf[i].lfFaceName, font_name), "expected %s, got %s\n",
                    font_name, efd.lf[i].lfFaceName);
         }
 
@@ -2554,7 +2961,28 @@ else
     ReleaseDC(0, hdc);
 }
 
-static INT CALLBACK enum_font_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_multi_charset_font_proc(const LOGFONTA *lf, const TEXTMETRICA *tm, DWORD type, LPARAM lParam)
+{
+    const NEWTEXTMETRICEXA *ntm = (const NEWTEXTMETRICEXA *)tm;
+    LOGFONTA *target = (LOGFONTA *)lParam;
+    const DWORD valid_bits = 0x003f01ff;
+    CHARSETINFO csi;
+    DWORD fs;
+
+    if (type != TRUETYPE_FONTTYPE) return TRUE;
+
+    if (TranslateCharsetInfo(ULongToPtr(target->lfCharSet), &csi, TCI_SRCCHARSET)) {
+        fs = ntm->ntmFontSig.fsCsb[0] & valid_bits;
+        if ((fs & csi.fs.fsCsb[0]) && (fs & ~csi.fs.fsCsb[0]) && (fs & FS_LATIN1)) {
+            *target = *lf;
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
+
+static INT CALLBACK enum_font_data_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     struct enum_font_data *efd = (struct enum_font_data *)lParam;
 
@@ -2568,14 +2996,14 @@ static INT CALLBACK enum_font_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm
     return 1;
 }
 
-static INT CALLBACK enum_fullname_data_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_fullname_data_proc(const LOGFONTA *lf, const TEXTMETRICA *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;
+        efnd->elf[efnd->total++] = *(ENUMLOGFONT*)lf;
     else
         trace("enum tests invalid; you have more than %d fonts\n", MAX_ENUM_FONTS);
 
@@ -2585,33 +3013,48 @@ static INT CALLBACK enum_fullname_data_proc(const LOGFONT *lf, const TEXTMETRIC
 static void test_EnumFontFamiliesEx_default_charset(void)
 {
     struct enum_font_data efd;
-    LOGFONT gui_font, enum_font;
-    DWORD ret;
+    LOGFONTA target, enum_font;
+    UINT acp;
     HDC hdc;
+    CHARSETINFO csi;
+
+    acp = GetACP();
+    if (!TranslateCharsetInfo(ULongToPtr(acp), &csi, TCI_SRCCODEPAGE)) {
+        skip("TranslateCharsetInfo failed for code page %u.\n", acp);
+        return;
+    }
 
-    ret = GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(gui_font), &gui_font);
-    ok(ret, "GetObject failed.\n");
-    if (!ret)
+    hdc = GetDC(0);
+    memset(&enum_font, 0, sizeof(enum_font));
+    enum_font.lfCharSet = csi.ciCharset;
+    target.lfFaceName[0] = '\0';
+    target.lfCharSet = csi.ciCharset;
+    EnumFontFamiliesExA(hdc, &enum_font, enum_multi_charset_font_proc, (LPARAM)&target, 0);
+    if (target.lfFaceName[0] == '\0') {
+        skip("suitable font isn't found for charset %d.\n", enum_font.lfCharSet);
         return;
+    }
+    if (acp == 874 || acp == 1255 || acp == 1256) {
+        /* these codepage use complex script, expecting ANSI_CHARSET here. */
+        target.lfCharSet = ANSI_CHARSET;
+    }
 
     efd.total = 0;
-
-    hdc = GetDC(0);
     memset(&enum_font, 0, sizeof(enum_font));
-    lstrcpy(enum_font.lfFaceName, gui_font.lfFaceName);
+    strcpy(enum_font.lfFaceName, target.lfFaceName);
     enum_font.lfCharSet = DEFAULT_CHARSET;
-    EnumFontFamiliesEx(hdc, &enum_font, enum_font_data_proc, (LPARAM)&efd, 0);
+    EnumFontFamiliesExA(hdc, &enum_font, enum_font_data_proc, (LPARAM)&efd, 0);
     ReleaseDC(0, hdc);
 
-    if (efd.total == 0) {
-        skip("'%s' is not found or not a TrueType font.\n", gui_font.lfFaceName);
+    trace("'%s' has %d charsets.\n", target.lfFaceName, efd.total);
+    if (efd.total < 2) {
+        ok(0, "EnumFontFamilies is broken. Expected >= 2, got %d.\n", efd.total);
         return;
     }
-    trace("'%s' has %d charsets.\n", gui_font.lfFaceName, efd.total);
 
-    ok(efd.lf[0].lfCharSet == gui_font.lfCharSet || broken(system_lang_id == LANG_ARABIC),
+    ok(efd.lf[0].lfCharSet == target.lfCharSet,
        "(%s) got charset %d expected %d\n",
-       efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, gui_font.lfCharSet);
+       efd.lf[0].lfFaceName, efd.lf[0].lfCharSet, target.lfCharSet);
 
     return;
 }
@@ -2733,21 +3176,6 @@ typedef struct
 } TT_OS2_V2;
 #include "poppack.h"
 
-#ifdef WORDS_BIGENDIAN
-#define GET_BE_WORD(x) (x)
-#define GET_BE_DWORD(x) (x)
-#else
-#define GET_BE_WORD(x) MAKEWORD(HIBYTE(x), LOBYTE(x))
-#define GET_BE_DWORD(x) MAKELONG(GET_BE_WORD(HIWORD(x)), GET_BE_WORD(LOWORD(x)));
-#endif
-
-#define MS_MAKE_TAG(ch0, ch1, ch2, ch3) \
-                    ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
-                    ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24))
-#define MS_OS2_TAG MS_MAKE_TAG('O','S','/','2')
-#define MS_CMAP_TAG MS_MAKE_TAG('c','m','a','p')
-#define MS_NAME_TAG MS_MAKE_TAG('n','a','m','e')
-
 typedef struct
 {
     USHORT version;
@@ -3051,7 +3479,7 @@ out:
     return r;
 }
 
-static void test_text_metrics(const LOGFONT *lf, const NEWTEXTMETRIC *ntm)
+static void test_text_metrics(const LOGFONTA *lf, const NEWTEXTMETRICA *ntm)
 {
     HDC hdc;
     HFONT hfont, hfont_old;
@@ -3089,19 +3517,13 @@ static void test_text_metrics(const LOGFONT *lf, const NEWTEXTMETRIC *ntm)
     ret = GetFontData(hdc, MS_OS2_TAG, 0, &tt_os2, size);
     ok(ret == size, "GetFontData should return %u not %u\n", size, ret);
 
-    ascent = GET_BE_WORD(tt_os2.usWinAscent);
-    descent = GET_BE_WORD(tt_os2.usWinDescent);
-    cell_height = ascent + descent;
-    ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
-       font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
-
     SetLastError(0xdeadbeef);
     ret = GetTextMetricsA(hdc, &tmA);
     ok(ret, "GetTextMetricsA error %u\n", GetLastError());
 
     if(!get_first_last_from_cmap(hdc, &cmap_first, &cmap_last, &cmap_type))
     {
-        skip("Unable to retrieve first and last glyphs from cmap\n");
+        skip("%s is not a Windows font, OS/2 metrics may be invalid.\n",font_name);
     }
     else
     {
@@ -3111,6 +3533,12 @@ static void test_text_metrics(const LOGFONT *lf, const NEWTEXTMETRIC *ntm)
         USHORT version;
         TEXTMETRICW tmW;
 
+        ascent = GET_BE_WORD(tt_os2.usWinAscent);
+        descent = GET_BE_WORD(tt_os2.usWinDescent);
+        cell_height = ascent + descent;
+        ok(ntm->ntmCellHeight == cell_height, "%s: ntmCellHeight %u != %u, os2.usWinAscent/os2.usWinDescent %u/%u\n",
+           font_name, ntm->ntmCellHeight, cell_height, ascent, descent);
+
         version = GET_BE_WORD(tt_os2.version);
 
         os2_first_char = GET_BE_WORD(tt_os2.usFirstCharIndex);
@@ -3276,14 +3704,14 @@ end_of_test:
     ReleaseDC(0, hdc);
 }
 
-static INT CALLBACK enum_truetype_font_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK enum_truetype_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
     INT *enumed = (INT *)lParam;
 
     if (type == TRUETYPE_FONTTYPE)
     {
         (*enumed)++;
-        test_text_metrics(lf, (const NEWTEXTMETRIC *)ntm);
+        test_text_metrics(lf, (const NEWTEXTMETRICA *)ntm);
     }
     return 1;
 }
@@ -3648,14 +4076,15 @@ todo_wine
     DeleteDC(hdc);
 }
 
-static int CALLBACK create_fixed_pitch_font_proc(const LOGFONT *lpelfe,
-                                                 const TEXTMETRIC *lpntme,
+static int CALLBACK create_fixed_pitch_font_proc(const LOGFONTA *lpelfe,
+                                                 const TEXTMETRICA *lpntme,
                                                  DWORD FontType, LPARAM lParam)
 {
-    const NEWTEXTMETRICEX *lpntmex = (const NEWTEXTMETRICEX *)lpntme;
+    const NEWTEXTMETRICEXA *lpntmex = (const NEWTEXTMETRICEXA *)lpntme;
     CHARSETINFO csi;
-    LOGFONT lf = *lpelfe;
+    LOGFONTA lf = *lpelfe;
     HFONT hfont;
+    DWORD found_subset;
 
     /* skip bitmap, proportional or vertical font */
     if ((FontType & TRUETYPE_FONTTYPE) == 0 ||
@@ -3668,10 +4097,29 @@ static int CALLBACK create_fixed_pitch_font_proc(const LOGFONT *lpelfe,
         (lpntmex->ntmFontSig.fsCsb[0] & csi.fs.fsCsb[0]) == 0)
         return 1;
 
+    /* skip linked font, like SimSun-ExtB */
+    switch (lpelfe->lfCharSet) {
+    case SHIFTJIS_CHARSET:
+        found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 17); /* Hiragana */
+        break;
+    case GB2312_CHARSET:
+    case CHINESEBIG5_CHARSET:
+        found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 16); /* CJK Symbols And Punctuation */
+        break;
+    case HANGEUL_CHARSET:
+        found_subset = lpntmex->ntmFontSig.fsUsb[1] & (1 << 24); /* Hangul Syllables */
+        break;
+    default:
+        found_subset = lpntmex->ntmFontSig.fsUsb[0] & (1 <<  0); /* Basic Latin */
+        break;
+    }
+    if (!found_subset)
+        return 1;
+
     /* test with an odd height */
     lf.lfHeight = -19;
     lf.lfWidth = 0;
-    hfont = CreateFontIndirect(&lf);
+    hfont = CreateFontIndirectA(&lf);
     if (hfont)
     {
         *(HFONT *)lParam = hfont;
@@ -3687,6 +4135,8 @@ static void test_GetGlyphOutline(void)
     LOGFONTA lf;
     HFONT hfont, old_hfont;
     INT ret, ret2;
+    const UINT fmt[] = { GGO_METRICS, GGO_BITMAP, GGO_GRAY2_BITMAP,
+                         GGO_GRAY4_BITMAP, GGO_GRAY8_BITMAP };
     static const struct
     {
         UINT cs;
@@ -3697,7 +4147,6 @@ static void test_GetGlyphOutline(void)
         {ANSI_CHARSET, 0x30, 0x30},
         {SHIFTJIS_CHARSET, 0x82a0, 0x3042},
         {HANGEUL_CHARSET, 0x8141, 0xac02},
-        {JOHAB_CHARSET, 0x8446, 0x3135},
         {GB2312_CHARSET, 0x8141, 0x4e04},
         {CHINESEBIG5_CHARSET, 0xa142, 0x3001}
     };
@@ -3763,17 +4212,81 @@ static void test_GetGlyphOutline(void)
        ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
     }
 
+    for (i = 0; i < sizeof(fmt) / sizeof(fmt[0]); ++i)
+    {
+        DWORD dummy;
+
+        memset(&gm, 0xab, sizeof(gm));
+        SetLastError(0xdeadbeef);
+        ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, NULL, &mat);
+        if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+        {
+            if (fmt[i] == GGO_METRICS)
+                ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+            else
+                ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+            ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+            ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+        }
+
+        memset(&gm, 0xab, sizeof(gm));
+        SetLastError(0xdeadbeef);
+        ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, 0, &dummy, &mat);
+        if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+        {
+            if (fmt[i] == GGO_METRICS)
+                ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+            else
+                ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+            ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+            ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+        }
+
+        memset(&gm, 0xab, sizeof(gm));
+        SetLastError(0xdeadbeef);
+        ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), NULL, &mat);
+        if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+        {
+            if (fmt[i] == GGO_METRICS)
+                ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+            else
+                ok(ret == 0, "%2d:GetGlyphOutlineW should return 0, got %d\n", fmt[i], ret);
+            ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+            ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+        }
+
+        memset(&gm, 0xab, sizeof(gm));
+        SetLastError(0xdeadbeef);
+        ret = GetGlyphOutlineW(hdc, ' ', fmt[i], &gm, sizeof(dummy), &dummy, &mat);
+        if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+        {
+            if (fmt[i] == GGO_METRICS) {
+                ok(ret != GDI_ERROR, "%2d:GetGlyphOutlineW should succeed, got %d\n", fmt[i], ret);
+                ok(gm.gmBlackBoxX == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxX);
+                ok(gm.gmBlackBoxY == 1, "%2d:expected 1, got %u\n", fmt[i], gm.gmBlackBoxY);
+            }
+            else
+            {
+                ok(ret == GDI_ERROR, "%2d:GetGlyphOutlineW should return GDI_ERROR, got %d\n", fmt[i], ret);
+                memset(&gm2, 0xab, sizeof(gm2));
+                ok(memcmp(&gm, &gm2, sizeof(GLYPHMETRICS)) == 0,
+                   "%2d:GLYPHMETRICS shouldn't be touched on error\n", fmt[i]);
+            }
+        }
+    }
+
     SelectObject(hdc, old_hfont);
     DeleteObject(hfont);
 
     for (i = 0; i < sizeof c / sizeof c[0]; ++i)
     {
         static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}};
+        TEXTMETRICA tm;
 
         lf.lfFaceName[0] = '\0';
         lf.lfCharSet = c[i].cs;
         lf.lfPitchAndFamily = 0;
-        if (EnumFontFamiliesEx(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
+        if (EnumFontFamiliesExA(hdc, &lf, create_font_proc, (LPARAM)&hfont, 0))
         {
             skip("TrueType font for charset %u is not installed\n", c[i].cs);
             continue;
@@ -3800,7 +4313,7 @@ static void test_GetGlyphOutline(void)
         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))
+        if (EnumFontFamiliesExA(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;
@@ -3812,18 +4325,18 @@ static void test_GetGlyphOutline(void)
             continue;
         }
 
-        ret = GetObject(hfont, sizeof lf, &lf);
+        ret = GetObjectA(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 = GetTextMetricsA(hdc, &tm);
+        ok(ret, "GetTextMetrics 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),
+        trace("Tests with height=%d,avg=%d,full=%d,face=%s,charset=%d\n",
+              -lf.lfHeight, tm.tmAveCharWidth, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+        ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
            "expected %d, got %d (%s:%d)\n",
-           gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+           tm.tmAveCharWidth * 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());
@@ -3832,20 +4345,20 @@ static void test_GetGlyphOutline(void)
            -lf.lfHeight, gm2.gmCellIncY, lf.lfFaceName, lf.lfCharSet);
 
         lf.lfItalic = TRUE;
-        hfont = CreateFontIndirect(&lf);
+        hfont = CreateFontIndirectA(&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 = GetTextMetricsA(hdc, &tm);
+        ok(ret, "GetTextMetrics 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),
+        ok(gm2.gmCellIncX == tm.tmAveCharWidth * 2 || broken(gm2.gmCellIncX == -lf.lfHeight),
            "expected %d, got %d (%s:%d)\n",
-           gm.gmCellIncX * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
+           tm.tmAveCharWidth * 2, gm2.gmCellIncX, lf.lfFaceName, lf.lfCharSet);
 
         lf.lfItalic = FALSE;
         lf.lfEscapement = lf.lfOrientation = 2700;
-        hfont = CreateFontIndirect(&lf);
+        hfont = CreateFontIndirectA(&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);
@@ -3894,17 +4407,17 @@ static void test_GetTextMetrics2(const char *fontname, int font_height)
 
     for (width = ave_width * 2; /* nothing*/; width += ave_width)
     {
-        hf = CreateFont(height, width, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
+        hf = CreateFontA(height, width, 0, 0, FW_REGULAR, FALSE, FALSE, FALSE,
                         DEFAULT_CHARSET, OUT_TT_PRECIS, CLIP_LH_ANGLES,
                         DEFAULT_QUALITY, VARIABLE_PITCH, fontname);
         ok(hf != 0, "CreateFont failed\n");
         of = SelectObject(hdc, hf);
-        ret = GetTextMetrics(hdc, &tm);
+        ret = GetTextMetricsA(hdc, &tm);
         ok(ret, "GetTextMetrics error %u\n", GetLastError());
         SelectObject(hdc, of);
         DeleteObject(hf);
 
-        if (match_off_by_1(tm.tmAveCharWidth, ave_width) || width / height > 200)
+        if (match_off_by_1(tm.tmAveCharWidth, ave_width, FALSE) || width / height > 200)
             break;
     }
 
@@ -3941,7 +4454,7 @@ static void test_CreateFontIndirect(void)
         hfont = CreateFontIndirectA(&lf);
         ok(hfont != 0, "CreateFontIndirectA failed\n");
         SetLastError(0xdeadbeef);
-        ret = GetObject(hfont, sizeof(getobj_lf), &getobj_lf);
+        ret = GetObjectA(hfont, sizeof(getobj_lf), &getobj_lf);
         ok(ret, "GetObject failed: %d\n", GetLastError());
         ok(lf.lfItalic == getobj_lf.lfItalic, "lfItalic: expect %02x got %02x\n", lf.lfItalic, getobj_lf.lfItalic);
         ok(lf.lfWeight == getobj_lf.lfWeight ||
@@ -3996,16 +4509,16 @@ static void *load_font(const char *font_name, DWORD *font_size)
     HANDLE file, mapping;
     void *font;
 
-    if (!GetWindowsDirectory(file_name, sizeof(file_name))) return NULL;
+    if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL;
     strcat(file_name, "\\fonts\\");
     strcat(file_name, font_name);
 
-    file = CreateFile(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+    file = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
     if (file == INVALID_HANDLE_VALUE) return NULL;
 
     *font_size = GetFileSize(file, NULL);
 
-    mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
+    mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
     if (!mapping)
     {
         CloseHandle(file);
@@ -4136,27 +4649,27 @@ static void test_AddFontMemResource(void)
     free_font(font);
 }
 
-static INT CALLBACK enum_fonts_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 {
-    LOGFONT *lf;
+    LOGFONTA *lf;
 
     if (type != TRUETYPE_FONTTYPE) return 1;
 
     ok(ntm->tmWeight == elf->lfWeight, "expected %d got %d\n", ntm->tmWeight, elf->lfWeight);
 
-    lf = (LOGFONT *)lparam;
+    lf = (LOGFONTA *)lparam;
     *lf = *elf;
     return 0;
 }
 
-static INT CALLBACK enum_all_fonts_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 {
     int ret;
-    LOGFONT *lf;
+    LOGFONTA *lf;
 
     if (type != TRUETYPE_FONTTYPE) return 1;
 
-    lf = (LOGFONT *)lparam;
+    lf = (LOGFONTA *)lparam;
     ret = strcmp(lf->lfFaceName, elf->lfFaceName);
     if(ret == 0)
     {
@@ -4167,7 +4680,7 @@ static INT CALLBACK enum_all_fonts_proc(const LOGFONT *elf, const TEXTMETRIC *nt
     return 1;
 }
 
-static INT CALLBACK enum_with_magic_retval_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lparam)
+static INT CALLBACK enum_with_magic_retval_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
 {
     return lparam;
 }
@@ -4175,7 +4688,7 @@ static INT CALLBACK enum_with_magic_retval_proc(const LOGFONT *elf, const TEXTME
 static void test_EnumFonts(void)
 {
     int ret;
-    LOGFONT lf;
+    LOGFONTA lf;
     HDC hdc;
 
     if (!is_truetype_font_installed("Arial"))
@@ -4194,55 +4707,55 @@ static void test_EnumFonts(void)
     hdc = CreateCompatibleDC(0);
 
     /* check that the enumproc's retval is returned */
-    ret = EnumFontFamilies(hdc, NULL, enum_with_magic_retval_proc, 0xcafe);
+    ret = EnumFontFamiliesA(hdc, NULL, enum_with_magic_retval_proc, 0xcafe);
     ok(ret == 0xcafe, "got %08x\n", ret);
 
-    ret = EnumFontFamilies(hdc, "Arial", enum_fonts_proc, (LPARAM)&lf);
+    ret = EnumFontFamiliesA(hdc, "Arial", enum_fonts_proc, (LPARAM)&lf);
     ok(!ret, "font Arial is not enumerated\n");
     ret = strcmp(lf.lfFaceName, "Arial");
     ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
     ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %d\n", lf.lfWeight);
 
-    lstrcpy(lf.lfFaceName, "Arial");
-    ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+    strcpy(lf.lfFaceName, "Arial");
+    ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
     ok(!ret, "font Arial is not enumerated\n");
     ret = strcmp(lf.lfFaceName, "Arial");
     ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
     ok(lf.lfWeight == FW_NORMAL, "expected FW_NORMAL got %d\n", lf.lfWeight);
 
-    ret = EnumFontFamilies(hdc, "Arial Bold", enum_fonts_proc, (LPARAM)&lf);
+    ret = EnumFontFamiliesA(hdc, "Arial Bold", enum_fonts_proc, (LPARAM)&lf);
     ok(!ret, "font Arial Bold is not enumerated\n");
     ret = strcmp(lf.lfFaceName, "Arial");
     ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
     ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %d\n", lf.lfWeight);
 
-    lstrcpy(lf.lfFaceName, "Arial Bold");
-    ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+    strcpy(lf.lfFaceName, "Arial Bold");
+    ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
     ok(ret, "font Arial Bold should not be enumerated\n");
 
-    ret = EnumFontFamilies(hdc, "Arial Bold Italic", enum_fonts_proc, (LPARAM)&lf);
+    ret = EnumFontFamiliesA(hdc, "Arial Bold Italic", enum_fonts_proc, (LPARAM)&lf);
     ok(!ret, "font Arial Bold Italic is not enumerated\n");
     ret = strcmp(lf.lfFaceName, "Arial");
     ok(!ret, "expected Arial got %s\n", lf.lfFaceName);
     ok(lf.lfWeight == FW_BOLD, "expected FW_BOLD got %d\n", lf.lfWeight);
 
-    lstrcpy(lf.lfFaceName, "Arial Bold Italic");
-    ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+    strcpy(lf.lfFaceName, "Arial Bold Italic");
+    ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
     ok(ret, "font Arial Bold Italic should not be enumerated\n");
 
-    ret = EnumFontFamilies(hdc, "Arial Italic Bold", enum_fonts_proc, (LPARAM)&lf);
+    ret = EnumFontFamiliesA(hdc, "Arial Italic Bold", enum_fonts_proc, (LPARAM)&lf);
     ok(ret, "font Arial Italic Bold  should not be enumerated\n");
 
-    lstrcpy(lf.lfFaceName, "Arial Italic Bold");
-    ret = EnumFontFamilies(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
+    strcpy(lf.lfFaceName, "Arial Italic Bold");
+    ret = EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)&lf);
     ok(ret, "font Arial Italic Bold should not be enumerated\n");
 
     DeleteDC(hdc);
 }
 
-static INT CALLBACK is_font_installed_fullname_proc(const LOGFONT *lf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
+static INT CALLBACK is_font_installed_fullname_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm, DWORD type, LPARAM lParam)
 {
-    const ENUMLOGFONT *elf = (const ENUMLOGFONT *)lf;
+    const ENUMLOGFONTA *elf = (const ENUMLOGFONTA *)lf;
     const char *fullname = (const char *)lParam;
 
     if (!strcmp((const char *)elf->elfFullName, fullname)) return 0;
@@ -4346,7 +4859,7 @@ static void test_fullname2_helper(const char *Family)
     lf.lfQuality = DEFAULT_QUALITY;
     lf.lfItalic = FALSE;
     lf.lfWeight = FW_DONTCARE;
-    lstrcpy(lf.lfFaceName, Family);
+    strcpy(lf.lfFaceName, Family);
     efnd.total = 0;
     EnumFontFamiliesExA(hdc, &lf, enum_fullname_data_proc, (LPARAM)&efnd, 0);
     if (efnd.total == 0)
@@ -4378,7 +4891,7 @@ static void test_fullname2_helper(const char *Family)
         otm_size = GetOutlineTextMetricsA(hdc, 0, NULL);
         otm = HeapAlloc(GetProcessHeap(), 0, otm_size);
         memset(otm, 0, otm_size);
-        ret = GetOutlineTextMetrics(hdc, otm_size, otm);
+        ret = GetOutlineTextMetricsA(hdc, otm_size, otm);
         ok(ret != 0, "GetOutlineTextMetrics fails!\n");
         if (ret == 0) continue;
 
@@ -4490,48 +5003,6 @@ static void test_fullname2(void)
 
 }
 
-static BOOL write_ttf_file(const char *fontname, char *tmp_name)
-{
-    char tmp_path[MAX_PATH];
-    HRSRC rsrc;
-    void *rsrc_data;
-    DWORD rsrc_size;
-    HANDLE hfile;
-    BOOL ret;
-
-    SetLastError(0xdeadbeef);
-    rsrc = FindResource(GetModuleHandle(0), fontname, RT_RCDATA);
-    ok(rsrc != 0, "FindResource error %d\n", GetLastError());
-    if (!rsrc) return FALSE;
-    SetLastError(0xdeadbeef);
-    rsrc_data = LockResource(LoadResource(GetModuleHandle(0), rsrc));
-    ok(rsrc_data != 0, "LockResource error %d\n", GetLastError());
-    if (!rsrc_data) return FALSE;
-    SetLastError(0xdeadbeef);
-    rsrc_size = SizeofResource(GetModuleHandle(0), rsrc);
-    ok(rsrc_size != 0, "SizeofResource error %d\n", GetLastError());
-    if (!rsrc_size) return FALSE;
-
-    SetLastError(0xdeadbeef);
-    ret = GetTempPath(MAX_PATH, tmp_path);
-    ok(ret, "GetTempPath() error %d\n", GetLastError());
-    SetLastError(0xdeadbeef);
-    ret = GetTempFileName(tmp_path, "ttf", 0, tmp_name);
-    ok(ret, "GetTempFileName() error %d\n", GetLastError());
-
-    SetLastError(0xdeadbeef);
-    hfile = CreateFile(tmp_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
-    ok(hfile != INVALID_HANDLE_VALUE, "CreateFile() error %d\n", GetLastError());
-    if (hfile == INVALID_HANDLE_VALUE) return FALSE;
-
-    SetLastError(0xdeadbeef);
-    ret = WriteFile(hfile, rsrc_data, rsrc_size, &rsrc_size, NULL);
-    ok(ret, "WriteFile() error %d\n", GetLastError());
-
-    CloseHandle(hfile);
-    return ret;
-}
-
 static void test_GetGlyphOutline_empty_contour(void)
 {
     HDC hdc;
@@ -4572,6 +5043,46 @@ static void test_GetGlyphOutline_empty_contour(void)
     ReleaseDC(NULL, hdc);
 }
 
+static void test_GetGlyphOutline_metric_clipping(void)
+{
+    HDC hdc;
+    LOGFONTA lf;
+    HFONT hfont, hfont_prev;
+    GLYPHMETRICS gm;
+    TEXTMETRICA tm;
+    DWORD ret;
+
+    memset(&lf, 0, sizeof(lf));
+    lf.lfHeight = 72;
+    lstrcpyA(lf.lfFaceName, "wine_test");
+
+    SetLastError(0xdeadbeef);
+    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");
+
+    SetLastError(0xdeadbeef);
+    ret = GetTextMetricsA(hdc, &tm);
+    ok(ret, "GetTextMetrics error %u\n", GetLastError());
+
+    GetGlyphOutlineA(hdc, 'A', GGO_METRICS, &gm, 0, NULL, &mat);
+    ok(gm.gmptGlyphOrigin.y <= tm.tmAscent,
+        "Glyph top(%d) exceeds ascent(%d)\n",
+        gm.gmptGlyphOrigin.y, tm.tmAscent);
+    GetGlyphOutlineA(hdc, 'D', GGO_METRICS, &gm, 0, NULL, &mat);
+    ok(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY >= -tm.tmDescent,
+        "Glyph bottom(%d) exceeds descent(%d)\n",
+        gm.gmptGlyphOrigin.y - gm.gmBlackBoxY, -tm.tmDescent);
+
+    SelectObject(hdc, hfont_prev);
+    DeleteObject(hfont);
+    ReleaseDC(NULL, hdc);
+}
+
 static void test_CreateScalableFontResource(void)
 {
     char ttf_name[MAX_PATH];
@@ -4598,41 +5109,41 @@ static void test_CreateScalableFontResource(void)
     ret = is_truetype_font_installed("wine_test");
     ok(!ret, "font wine_test should not be enumerated\n");
 
-    ret = GetTempPath(MAX_PATH, tmp_path);
+    ret = GetTempPathA(MAX_PATH, tmp_path);
     ok(ret, "GetTempPath() error %d\n", GetLastError());
-    ret = GetTempFileName(tmp_path, "fot", 0, fot_name);
+    ret = GetTempFileNameA(tmp_path, "fot", 0, fot_name);
     ok(ret, "GetTempFileName() error %d\n", GetLastError());
 
-    ret = GetFileAttributes(fot_name);
+    ret = GetFileAttributesA(fot_name);
     ok(ret != INVALID_FILE_ATTRIBUTES, "file %s does not exist\n", fot_name);
 
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, ttf_name, NULL);
+    ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
     ok(!ret, "CreateScalableFontResource() should fail\n");
     ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, ttf_name, "");
+    ret = CreateScalableFontResourceA(0, fot_name, ttf_name, "");
     ok(!ret, "CreateScalableFontResource() should fail\n");
     ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
 
     file_part = strrchr(ttf_name, '\\');
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, file_part, tmp_path);
+    ret = CreateScalableFontResourceA(0, fot_name, file_part, tmp_path);
     ok(!ret, "CreateScalableFontResource() should fail\n");
     ok(GetLastError() == ERROR_FILE_EXISTS, "not expected error %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, "random file name", tmp_path);
+    ret = CreateScalableFontResourceA(0, fot_name, "random file name", tmp_path);
     ok(!ret, "CreateScalableFontResource() should fail\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %d\n", GetLastError());
 
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, NULL, ttf_name);
+    ret = CreateScalableFontResourceA(0, fot_name, NULL, ttf_name);
     ok(!ret, "CreateScalableFontResource() should fail\n");
     ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %d\n", GetLastError());
 
-    ret = DeleteFile(fot_name);
+    ret = DeleteFileA(fot_name);
     ok(ret, "DeleteFile() error %d\n", GetLastError());
 
     ret = pRemoveFontResourceExA(fot_name, 0, 0);
@@ -4640,7 +5151,7 @@ static void test_CreateScalableFontResource(void)
 
     /* test public font resource */
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(0, fot_name, ttf_name, NULL);
+    ret = CreateScalableFontResourceA(0, fot_name, ttf_name, NULL);
     ok(ret, "CreateScalableFontResource() error %d\n", GetLastError());
 
     ret = is_truetype_font_installed("wine_test");
@@ -4654,6 +5165,7 @@ static void test_CreateScalableFontResource(void)
     ok(ret, "font wine_test should be enumerated\n");
 
     test_GetGlyphOutline_empty_contour();
+    test_GetGlyphOutline_metric_clipping();
 
     ret = pRemoveFontResourceExA(fot_name, FR_PRIVATE, 0);
     ok(!ret, "RemoveFontResourceEx() with not matching flags should fail\n");
@@ -4684,11 +5196,11 @@ static void test_CreateScalableFontResource(void)
     ret = pRemoveFontResourceExA(fot_name, 0, 0);
     ok(!ret, "RemoveFontResourceEx() should fail\n");
 
-    DeleteFile(fot_name);
+    DeleteFileA(fot_name);
 
     /* test hidden font resource */
     SetLastError(0xdeadbeef);
-    ret = CreateScalableFontResource(1, fot_name, ttf_name, NULL);
+    ret = CreateScalableFontResourceA(1, fot_name, ttf_name, NULL);
     ok(ret, "CreateScalableFontResource() error %d\n", GetLastError());
 
     ret = is_truetype_font_installed("wine_test");
@@ -4713,8 +5225,8 @@ static void test_CreateScalableFontResource(void)
     ret = pRemoveFontResourceExA(fot_name, 0, 0);
     ok(!ret, "RemoveFontResourceEx() should fail\n");
 
-    DeleteFile(fot_name);
-    DeleteFile(ttf_name);
+    DeleteFileA(fot_name);
+    DeleteFileA(ttf_name);
 }
 
 static void check_vertical_font(const char *name, BOOL *installed, BOOL *selected, GLYPHMETRICS *gm, WORD *gi)
@@ -4768,13 +5280,103 @@ static void check_vertical_font(const char *name, BOOL *installed, BOOL *selecte
     ReleaseDC(NULL, hdc);
 }
 
+static void check_vertical_metrics(const char *face)
+{
+    LOGFONTA lf;
+    HFONT hfont, hfont_prev;
+    HDC hdc;
+    DWORD ret;
+    GLYPHMETRICS rgm, vgm;
+    const UINT code = 0x5EAD, height = 1000;
+    WORD idx;
+    ABC abc;
+    OUTLINETEXTMETRICA otm;
+    USHORT numOfLongVerMetrics;
+
+    hdc = GetDC(NULL);
+
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, face);
+    lf.lfHeight = -height;
+    lf.lfCharSet = DEFAULT_CHARSET;
+    lf.lfEscapement = lf.lfOrientation = 900;
+    hfont = CreateFontIndirectA(&lf);
+    hfont_prev = SelectObject(hdc, hfont);
+    ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &rgm, 0, NULL, &mat);
+    ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
+    ret = GetCharABCWidthsW(hdc, code, code, &abc);
+    ok(ret, "GetCharABCWidthsW failed\n");
+    DeleteObject(SelectObject(hdc, hfont_prev));
+
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "@");
+    strcat(lf.lfFaceName, face);
+    lf.lfHeight = -height;
+    lf.lfCharSet = DEFAULT_CHARSET;
+    hfont = CreateFontIndirectA(&lf);
+    hfont_prev = SelectObject(hdc, hfont);
+    ret = GetGlyphOutlineW(hdc, code, GGO_METRICS, &vgm, 0, NULL, &mat);
+    ok(ret != GDI_ERROR, "GetGlyphOutlineW failed\n");
+
+    memset(&otm, 0, sizeof(otm));
+    otm.otmSize = sizeof(otm);
+    ret = GetOutlineTextMetricsA(hdc, sizeof(otm), &otm);
+    ok(ret != 0, "GetOutlineTextMetricsA failed\n");
+
+    if (GetFontData(hdc, MS_MAKE_TAG('v','h','e','a'), sizeof(SHORT) * 17,
+                    &numOfLongVerMetrics, sizeof(numOfLongVerMetrics)) != GDI_ERROR) {
+        int offset;
+        SHORT topSideBearing;
+
+        if (!pGetGlyphIndicesW) {
+            win_skip("GetGlyphIndices is not available on this platform\n");
+        }
+        else {
+            ret = pGetGlyphIndicesW(hdc, (LPCWSTR)&code, 1, &idx, 0);
+            ok(ret != 0, "GetGlyphIndicesW failed\n");
+            numOfLongVerMetrics = GET_BE_WORD(numOfLongVerMetrics);
+            if (numOfLongVerMetrics > idx)
+                offset = idx * 2 + 1;
+            else
+                offset = numOfLongVerMetrics * 2 + (idx - numOfLongVerMetrics);
+            ret = GetFontData(hdc, MS_MAKE_TAG('v','m','t','x'), offset * sizeof(SHORT),
+                              &topSideBearing, sizeof(SHORT));
+            ok(ret != GDI_ERROR, "GetFontData(vmtx) failed\n");
+            topSideBearing = GET_BE_WORD(topSideBearing);
+            ok(match_off_by_1(vgm.gmptGlyphOrigin.x,
+                              MulDiv(topSideBearing, height, otm.otmEMSquare), FALSE),
+               "expected %d, got %d\n",
+               MulDiv(topSideBearing, height, otm.otmEMSquare), vgm.gmptGlyphOrigin.x);
+        }
+    }
+    else
+    {
+        ok(vgm.gmptGlyphOrigin.x == rgm.gmptGlyphOrigin.x + vgm.gmCellIncX + otm.otmDescent,
+           "got %d, expected rgm.origin.x(%d) + vgm.cellIncX(%d) + descent(%d)\n",
+           vgm.gmptGlyphOrigin.x, rgm.gmptGlyphOrigin.x, vgm.gmCellIncX, otm.otmDescent);
+    }
+
+    ok(vgm.gmptGlyphOrigin.y == abc.abcA + abc.abcB + otm.otmDescent ||
+       broken(vgm.gmptGlyphOrigin.y == abc.abcA + abc.abcB - otm.otmTextMetrics.tmDescent) /* win2k */,
+       "got %d, expected abcA(%d) + abcB(%u) + descent(%d)\n",
+       (INT)vgm.gmptGlyphOrigin.y, abc.abcA, abc.abcB, otm.otmDescent);
+
+    DeleteObject(SelectObject(hdc, hfont_prev));
+    ReleaseDC(NULL, hdc);
+}
+
 static void test_vertical_font(void)
 {
     char ttf_name[MAX_PATH];
-    int num;
+    int num, i;
     BOOL ret, installed, selected;
     GLYPHMETRICS gm;
     WORD hgi, vgi;
+    const char* face_list[] = {
+        "@WineTestVertical", /* has vmtx table */
+        "@Ume Gothic",       /* doesn't have vmtx table */
+        "@MS UI Gothic",     /* has vmtx table, available on native */
+    };
 
     if (!pAddFontResourceExA || !pRemoveFontResourceExA || !pGetGlyphIndicesW)
     {
@@ -4791,29 +5393,39 @@ static void test_vertical_font(void)
     num = pAddFontResourceExA(ttf_name, FR_PRIVATE, 0);
     ok(num == 2, "AddFontResourceExA should add 2 fonts from vertical.ttf\n");
 
-    check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &hgi);
-    ok(installed, "@WineTestVertical is not installed\n");
-    ok(selected, "@WineTestVertical is not selected\n");
+    check_vertical_font("WineTestVertical", &installed, &selected, &gm, &hgi);
+    ok(installed, "WineTestVertical is not installed\n");
+    ok(selected, "WineTestVertical is not selected\n");
     ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
        "gmBlackBoxX(%u) should be greater than gmBlackBoxY(%u) if horizontal\n",
        gm.gmBlackBoxX, gm.gmBlackBoxY);
 
-    check_vertical_font("@@WineTestVertical", &installed, &selected, &gm, &vgi);
-    ok(installed, "@@WineTestVertical is not installed\n");
-    ok(selected, "@@WineTestVertical is not selected\n");
-    ok(gm.gmBlackBoxX < gm.gmBlackBoxY,
+    check_vertical_font("@WineTestVertical", &installed, &selected, &gm, &vgi);
+    ok(installed, "@WineTestVertical is not installed\n");
+    ok(selected, "@WineTestVertical is not selected\n");
+    ok(gm.gmBlackBoxX > gm.gmBlackBoxY,
        "gmBlackBoxX(%u) should be less than gmBlackBoxY(%u) if vertical\n",
        gm.gmBlackBoxX, gm.gmBlackBoxY);
 
-    ok(hgi == vgi, "different glyph h:%u v:%u\n", hgi, vgi);
+    ok(hgi != vgi, "same glyph h:%u v:%u\n", hgi, vgi);
+
+    for (i = 0; i < sizeof(face_list)/sizeof(face_list[0]); i++) {
+        const char* face = face_list[i];
+        if (!is_truetype_font_installed(face)) {
+            skip("%s is not installed\n", face);
+            continue;
+        }
+        trace("Testing %s...\n", face);
+        check_vertical_metrics(&face[1]);
+    }
 
     ret = pRemoveFontResourceExA(ttf_name, FR_PRIVATE, 0);
     ok(ret, "RemoveFontResourceEx() error %d\n", GetLastError());
 
-    DeleteFile(ttf_name);
+    DeleteFileA(ttf_name);
 }
 
-static INT CALLBACK has_vertical_font_proc(const LOGFONT *lf, const TEXTMETRIC *ntm,
+static INT CALLBACK has_vertical_font_proc(const LOGFONTA *lf, const TEXTMETRICA *ntm,
                                            DWORD type, LPARAM lParam)
 {
     if (lf->lfFaceName[0] == '@') {
@@ -4842,7 +5454,7 @@ static void test_east_asian_font_selection(void)
         lf.lfFaceName[0] = '\0';
         lf.lfCharSet = charset[i];
 
-        if (EnumFontFamiliesEx(hdc, &lf, has_vertical_font_proc, 0, 0))
+        if (EnumFontFamiliesExA(hdc, &lf, has_vertical_font_proc, 0, 0))
         {
             skip("Vertical font for charset %u is not installed\n", charset[i]);
             continue;
@@ -4870,20 +5482,21 @@ static void test_east_asian_font_selection(void)
     ReleaseDC(NULL, hdc);
 }
 
-static int get_font_dpi(const LOGFONT *lf)
+static int get_font_dpi(const LOGFONTA *lf, int *height)
 {
     HDC hdc = CreateCompatibleDC(0);
     HFONT hfont;
-    TEXTMETRIC tm;
+    TEXTMETRICA tm;
     int ret;
 
-    hfont = CreateFontIndirect(lf);
+    hfont = CreateFontIndirectA(lf);
     ok(hfont != 0, "CreateFontIndirect failed\n");
 
     SelectObject(hdc, hfont);
-    ret = GetTextMetrics(hdc, &tm);
+    ret = GetTextMetricsA(hdc, &tm);
     ok(ret, "GetTextMetrics failed\n");
     ret = tm.tmDigitizedAspectX;
+    if (height) *height = tm.tmHeight;
 
     DeleteDC(hdc);
     DeleteObject(hfont);
@@ -4900,49 +5513,49 @@ static void test_stock_fonts(void)
     };
     static const struct test_data
     {
-        int charset, weight, height, dpi;
+        int charset, weight, height, height_pixels, 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" },
+            { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "Courier" },
+            { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 120, "Courier" },
             { 0 }
         },
         { /* ANSI_VAR_FONT */
-            { DEFAULT_CHARSET, FW_NORMAL, 12, 96, "MS Sans Serif" },
-            { DEFAULT_CHARSET, FW_NORMAL, 12, 120, "MS Sans Serif" },
+            { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 96, "MS Sans Serif" },
+            { DEFAULT_CHARSET, FW_NORMAL, 12, 13, 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" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
+            { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
+            { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
+            { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
+            { DEFAULT_CHARSET, FW_BOLD, 20, 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" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, 18, 18, 96, "System" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, 22, 22, 120, "System" },
+            { HANGEUL_CHARSET, FW_NORMAL, 16, 16, 96, "System" },
+            { HANGEUL_CHARSET, FW_NORMAL, 20, 20, 120, "System" },
+            { DEFAULT_CHARSET, FW_BOLD, 16, 16, 96, "System" },
+            { DEFAULT_CHARSET, FW_BOLD, 20, 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" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, -12, 15, 96, "?MS UI Gothic" },
+            { SHIFTJIS_CHARSET, FW_NORMAL, -15, 18, 120, "?MS UI Gothic" },
+            { HANGEUL_CHARSET, FW_NORMAL, -12, 15, 96, "?Gulim" },
+            { HANGEUL_CHARSET, FW_NORMAL, -15, 18, 120, "?Gulim" },
+            { GB2312_CHARSET, FW_NORMAL, -12, 15, 96, "?SimHei" },
+            { GB2312_CHARSET, FW_NORMAL, -15, 18, 120, "?SimHei" },
+            { CHINESEBIG5_CHARSET, FW_NORMAL, -12, 15, 96, "?MingLiU" },
+            { CHINESEBIG5_CHARSET, FW_NORMAL, -15, 18, 120, "?MingLiU" },
+            { DEFAULT_CHARSET, FW_NORMAL, -11, 13, 96, "MS Shell Dlg" },
+            { DEFAULT_CHARSET, FW_NORMAL, -13, 16, 120, "MS Shell Dlg" },
             { 0 }
         }
     };
@@ -4951,13 +5564,13 @@ static void test_stock_fonts(void)
     for (i = 0; i < sizeof(font)/sizeof(font[0]); i++)
     {
         HFONT hfont;
-        LOGFONT lf;
-        int ret;
+        LOGFONTA lf;
+        int ret, height;
 
         hfont = GetStockObject(font[i]);
         ok(hfont != 0, "%d: GetStockObject(%d) failed\n", i, font[i]);
 
-        ret = GetObject(hfont, sizeof(lf), &lf);
+        ret = GetObjectA(hfont, sizeof(lf), &lf);
         if (ret != sizeof(lf))
         {
             /* NT4 */
@@ -4972,7 +5585,7 @@ static void test_stock_fonts(void)
                 continue;
             }
 
-            ret = get_font_dpi(&lf);
+            ret = get_font_dpi(&lf, &height);
             if (ret != td[i][j].dpi)
             {
                 trace("%d(%d): font %s %d dpi doesn't match test data %d\n",
@@ -4980,6 +5593,17 @@ static void test_stock_fonts(void)
                 continue;
             }
 
+            /* FIXME: Remove once Wine is fixed */
+            if (td[i][j].dpi != 96 &&
+                /* MS Sans Serif for 120 dpi and higher should include 12 pixel bitmap set */
+                ((!strcmp(td[i][j].face_name, "MS Sans Serif") && td[i][j].height == 12) ||
+                /* System for 120 dpi and higher should include 20 pixel bitmap set */
+                (!strcmp(td[i][j].face_name, "System") && td[i][j].height > 16)))
+            todo_wine
+            ok(height == td[i][j].height_pixels, "%d(%d): expected height %d, got %d\n", i, j, td[i][j].height_pixels, height);
+            else
+            ok(height == td[i][j].height_pixels, "%d(%d): expected height %d, got %d\n", i, j, td[i][j].height_pixels, height);
+
             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] == '?')
@@ -4991,13 +5615,402 @@ static void test_stock_fonts(void)
             }
             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);
+                ok(!strcmp(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;
         }
     }
 }
 
+static void test_max_height(void)
+{
+    HDC hdc;
+    LOGFONTA lf;
+    HFONT hfont, hfont_old;
+    TEXTMETRICA tm1, tm;
+    BOOL r;
+    LONG invalid_height[] = { -65536, -123456, 123456 };
+    size_t i;
+
+    memset(&tm1, 0, sizeof(tm1));
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Tahoma");
+    lf.lfHeight = -1;
+
+    hdc = GetDC(NULL);
+
+    /* get 1 ppem value */
+    hfont = CreateFontIndirectA(&lf);
+    hfont_old = SelectObject(hdc, hfont);
+    r = GetTextMetricsA(hdc, &tm1);
+    ok(r, "GetTextMetrics failed\n");
+    ok(tm1.tmHeight > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+    ok(tm1.tmAveCharWidth > 0, "expected a positive value, got %d\n", tm1.tmHeight);
+    DeleteObject(SelectObject(hdc, hfont_old));
+
+    /* test the largest value */
+    lf.lfHeight = -((1 << 16) - 1);
+    hfont = CreateFontIndirectA(&lf);
+    hfont_old = SelectObject(hdc, hfont);
+    memset(&tm, 0, sizeof(tm));
+    r = GetTextMetricsA(hdc, &tm);
+    ok(r, "GetTextMetrics failed\n");
+    ok(tm.tmHeight > tm1.tmHeight,
+       "expected greater than 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+    ok(tm.tmAveCharWidth > tm1.tmAveCharWidth,
+       "expected greater than 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+    DeleteObject(SelectObject(hdc, hfont_old));
+
+    /* test an invalid value */
+    for (i = 0; i < sizeof(invalid_height)/sizeof(invalid_height[0]); i++) {
+        lf.lfHeight = invalid_height[i];
+        hfont = CreateFontIndirectA(&lf);
+        hfont_old = SelectObject(hdc, hfont);
+        memset(&tm, 0, sizeof(tm));
+        r = GetTextMetricsA(hdc, &tm);
+        ok(r, "GetTextMetrics failed\n");
+        ok(tm.tmHeight == tm1.tmHeight,
+           "expected 1 ppem value (%d), got %d\n", tm1.tmHeight, tm.tmHeight);
+        ok(tm.tmAveCharWidth == tm1.tmAveCharWidth,
+           "expected 1 ppem value (%d), got %d\n", tm1.tmAveCharWidth, tm.tmAveCharWidth);
+        DeleteObject(SelectObject(hdc, hfont_old));
+    }
+
+    ReleaseDC(NULL, hdc);
+    return;
+}
+
+static void test_vertical_order(void)
+{
+    struct enum_font_data efd;
+    LOGFONTA lf;
+    HDC hdc;
+    int i, j;
+
+    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;
+    efd.total = 0;
+    EnumFontFamiliesExA(hdc, &lf, enum_font_data_proc, (LPARAM)&efd, 0);
+    for (i = 0; i < efd.total; i++)
+    {
+        if (efd.lf[i].lfFaceName[0] != '@') continue;
+        for (j = 0; j < efd.total; j++)
+        {
+            if (!strcmp(efd.lf[i].lfFaceName + 1, efd.lf[j].lfFaceName))
+            {
+                ok(i > j,"Found vertical font %s before its horizontal version\n", efd.lf[i].lfFaceName);
+                break;
+            }
+        }
+    }
+    DeleteDC( hdc );
+}
+
+static void test_GetCharWidth32(void)
+{
+    BOOL ret;
+    HDC hdc;
+    LOGFONTA lf;
+    HFONT hfont;
+    INT bufferA;
+    INT bufferW;
+    HWND hwnd;
+
+    if (!pGetCharWidth32A || !pGetCharWidth32W)
+    {
+        win_skip("GetCharWidth32A/W not available on this platform\n");
+        return;
+    }
+
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "System");
+    lf.lfHeight = 20;
+
+    hfont = CreateFontIndirectA(&lf);
+    hdc = GetDC(0);
+    hfont = SelectObject(hdc, hfont);
+
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ret = pGetCharWidth32A(hdc, 'a', 'a', &bufferA);
+    ok(ret, "GetCharWidth32A should have succeeded\n");
+    ok (bufferA == bufferW, "Widths should be the same\n");
+    ok (bufferA > 0," Width should be greater than zero\n");
+
+    hfont = SelectObject(hdc, hfont);
+    DeleteObject(hfont);
+    ReleaseDC(NULL, hdc);
+
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Tahoma");
+    lf.lfHeight = 20;
+
+    hfont = CreateFontIndirectA(&lf);
+    hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
+                           0, 0, 0, NULL);
+    hdc = GetDC(hwnd);
+    SetMapMode( hdc, MM_ANISOTROPIC );
+    SelectObject(hdc, hfont);
+
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetWindowExtEx(hdc, -1,-1,NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+    SetWindowExtEx(hdc, 1,1,NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
+
+    hwnd = CreateWindowExA(WS_EX_LAYOUTRTL, "static", "", WS_POPUP, 0,0,100,100,
+                           0, 0, 0, NULL);
+    hdc = GetDC(hwnd);
+    SetMapMode( hdc, MM_ANISOTROPIC );
+    SelectObject(hdc, hfont);
+
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetWindowExtEx(hdc, -1,-1,NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetWindowExtEx(hdc, 1,1,NULL);
+    SetGraphicsMode(hdc, GM_COMPATIBLE);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    ok (bufferW > 0," Width should be greater than zero\n");
+    SetGraphicsMode(hdc, GM_ADVANCED);
+    ret = pGetCharWidth32W(hdc, 'a', 'a', &bufferW);
+    ok(ret, "GetCharWidth32W should have succeeded\n");
+    todo_wine ok (bufferW > 0," Width should be greater than zero\n");
+
+    ReleaseDC(hwnd, hdc);
+    DestroyWindow(hwnd);
+    DeleteObject(hfont);
+}
+
+static void test_fake_bold_font(void)
+{
+    HDC hdc;
+    HFONT hfont, hfont_old;
+    LOGFONTA lf;
+    BOOL ret;
+    TEXTMETRICA tm[2];
+    ABC abc[2];
+    INT w[2];
+
+    if (!pGetCharWidth32A || !pGetCharABCWidthsA) {
+        win_skip("GetCharWidth32A/GetCharABCWidthA is not available on this platform\n");
+        return;
+    }
+
+    /* Test outline font */
+    memset(&lf, 0, sizeof(lf));
+    strcpy(lf.lfFaceName, "Wingdings");
+    lf.lfWeight = FW_NORMAL;
+    lf.lfCharSet = SYMBOL_CHARSET;
+    hfont = CreateFontIndirectA(&lf);
+
+    hdc = GetDC(NULL);
+    hfont_old = SelectObject(hdc, hfont);
+
+    /* base metrics */
+    ret = GetTextMetricsA(hdc, &tm[0]);
+    ok(ret, "got %d\n", ret);
+    ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[0]);
+    ok(ret, "got %d\n", ret);
+
+    lf.lfWeight = FW_BOLD;
+    hfont = CreateFontIndirectA(&lf);
+    DeleteObject(SelectObject(hdc, hfont));
+
+    /* bold metrics */
+    ret = GetTextMetricsA(hdc, &tm[1]);
+    ok(ret, "got %d\n", ret);
+    ret = pGetCharABCWidthsA(hdc, 0x76, 0x76, &abc[1]);
+    ok(ret, "got %d\n", ret);
+
+    DeleteObject(SelectObject(hdc, hfont_old));
+    ReleaseDC(NULL, hdc);
+
+    /* compare results (outline) */
+    ok(tm[0].tmHeight == tm[1].tmHeight, "expected %d, got %d\n", tm[0].tmHeight, tm[1].tmHeight);
+    ok(tm[0].tmAscent == tm[1].tmAscent, "expected %d, got %d\n", tm[0].tmAscent, tm[1].tmAscent);
+    ok(tm[0].tmDescent == tm[1].tmDescent, "expected %d, got %d\n", tm[0].tmDescent, tm[1].tmDescent);
+    ok((tm[0].tmAveCharWidth + 1) == tm[1].tmAveCharWidth,
+       "expected %d, got %d\n", tm[0].tmAveCharWidth + 1, tm[1].tmAveCharWidth);
+    ok((tm[0].tmMaxCharWidth + 1) == tm[1].tmMaxCharWidth,
+       "expected %d, got %d\n", tm[0].tmMaxCharWidth + 1, tm[1].tmMaxCharWidth);
+    ok(tm[0].tmOverhang == tm[1].tmOverhang, "expected %d, got %d\n", tm[0].tmOverhang, tm[1].tmOverhang);
+    w[0] = abc[0].abcA + abc[0].abcB + abc[0].abcC;
+    w[1] = abc[1].abcA + abc[1].abcB + abc[1].abcC;
+    ok((w[0] + 1) == w[1], "expected %d, got %d\n", w[0] + 1, w[1]);
+
+}
+
+static void test_bitmap_font_glyph_index(void)
+{
+    const WCHAR text[] = {'#','!','/','b','i','n','/','s','h',0};
+    const struct {
+        LPCSTR face;
+        BYTE charset;
+    } bitmap_font_list[] = {
+        { "Courier", ANSI_CHARSET },
+        { "Small Fonts", ANSI_CHARSET },
+        { "Fixedsys", DEFAULT_CHARSET },
+        { "System", DEFAULT_CHARSET }
+    };
+    HDC hdc;
+    LOGFONTA lf;
+    HFONT hFont;
+    CHAR facename[LF_FACESIZE];
+    BITMAPINFO bmi;
+    HBITMAP hBmp[2];
+    void *pixels[2];
+    int i, j;
+    DWORD ret;
+    BITMAP bmp;
+    TEXTMETRICA tm;
+    CHARSETINFO ci;
+    BYTE chr = '\xA9';
+
+    if (!pGetGlyphIndicesW || !pGetGlyphIndicesA) {
+        win_skip("GetGlyphIndices is unavailable\n");
+        return;
+    }
+
+    hdc = CreateCompatibleDC(0);
+    ok(hdc != NULL, "CreateCompatibleDC failed\n");
+
+    memset(&bmi, 0, sizeof(bmi));
+    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+    bmi.bmiHeader.biBitCount = 32;
+    bmi.bmiHeader.biPlanes = 1;
+    bmi.bmiHeader.biWidth = 128;
+    bmi.bmiHeader.biHeight = 32;
+    bmi.bmiHeader.biCompression = BI_RGB;
+
+    for (i = 0; i < sizeof(bitmap_font_list)/sizeof(bitmap_font_list[0]); i++) {
+        memset(&lf, 0, sizeof(lf));
+        lf.lfCharSet = bitmap_font_list[i].charset;
+        strcpy(lf.lfFaceName, bitmap_font_list[i].face);
+        hFont = CreateFontIndirectA(&lf);
+        ok(hFont != NULL, "Can't create font (%s:%d)\n", lf.lfFaceName, lf.lfCharSet);
+        hFont = SelectObject(hdc, hFont);
+        ret = GetTextMetricsA(hdc, &tm);
+        ok(ret, "GetTextMetric failed\n");
+        ret = GetTextFaceA(hdc, sizeof(facename), facename);
+        ok(ret, "GetTextFace failed\n");
+        if (tm.tmPitchAndFamily & TMPF_TRUETYPE) {
+            skip("TrueType font (%s) was selected for \"%s\"\n", facename, bitmap_font_list[i].face);
+            continue;
+        }
+        if (lstrcmpiA(facename, lf.lfFaceName) != 0) {
+            skip("expected %s, got %s\n", lf.lfFaceName, facename);
+            continue;
+        }
+
+        for (j = 0; j < 2; j++) {
+            HBITMAP hBmpPrev;
+            hBmp[j] = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &pixels[j], NULL, 0);
+            ok(hBmp[j] != NULL, "Can't create DIB\n");
+            hBmpPrev = SelectObject(hdc, hBmp[j]);
+            switch (j) {
+            case 0:
+                ret = ExtTextOutW(hdc, 0, 0, 0, NULL, text, lstrlenW(text), NULL);
+                break;
+            case 1:
+            {
+                int len = lstrlenW(text);
+                LPWORD indices = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WORD));
+                ret = pGetGlyphIndicesW(hdc, text, len, indices, 0);
+                ok(ret, "GetGlyphIndices failed\n");
+                ok(memcmp(indices, text, sizeof(WORD) * len) == 0,
+                   "Glyph indices and text are different for %s:%d\n", lf.lfFaceName, tm.tmCharSet);
+                ret = ExtTextOutW(hdc, 0, 0, ETO_GLYPH_INDEX, NULL, indices, len, NULL);
+                HeapFree(GetProcessHeap(), 0, indices);
+                break;
+            }
+            }
+            ok(ret, "ExtTextOutW failed\n");
+            SelectObject(hdc, hBmpPrev);
+        }
+
+        GetObjectA(hBmp[0], sizeof(bmp), &bmp);
+        ok(memcmp(pixels[0], pixels[1], bmp.bmHeight * bmp.bmWidthBytes) == 0,
+           "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+
+        ret = TranslateCharsetInfo((LPDWORD)(DWORD_PTR)tm.tmCharSet, &ci, TCI_SRCCHARSET);
+        if (!ret) {
+            skip("Can't get charset info for (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+            goto next;
+        }
+        if (IsDBCSLeadByteEx(ci.ciACP, chr)) {
+            skip("High-ascii character is not defined in codepage %d\n", ci.ciACP);
+            goto next;
+        }
+
+        for (j = 0; j < 2; j++) {
+            HBITMAP hBmpPrev;
+            WORD code;
+            hBmpPrev = SelectObject(hdc, hBmp[j]);
+            switch (j) {
+            case 0:
+                ret = ExtTextOutA(hdc, 100, 0, 0, NULL, (LPCSTR)&chr, 1, NULL);
+                break;
+            case 1:
+                ret = pGetGlyphIndicesA(hdc, (LPCSTR)&chr, 1, &code, 0);
+                ok(ret, "GetGlyphIndices failed\n");
+                ok(code == chr, "expected %02x, got %02x (%s:%d)\n", chr, code, lf.lfFaceName, tm.tmCharSet);
+                ret = ExtTextOutA(hdc, 100, 0, ETO_GLYPH_INDEX, NULL, (LPCSTR)&code, 1, NULL);
+                break;
+            }
+            ok(ret, "ExtTextOutA failed\n");
+            SelectObject(hdc, hBmpPrev);
+        }
+
+        ok(memcmp(pixels[0], pixels[1], bmp.bmHeight * bmp.bmWidthBytes) == 0,
+           "Images are different (%s:%d)\n", lf.lfFaceName, tm.tmCharSet);
+    next:
+        for (j = 0; j < 2; j++)
+            DeleteObject(hBmp[j]);
+        hFont = SelectObject(hdc, hFont);
+        DeleteObject(hFont);
+    }
+
+    DeleteDC(hdc);
+}
+
 START_TEST(font)
 {
     init();
@@ -5054,6 +6067,11 @@ START_TEST(font)
     test_fullname();
     test_fullname2();
     test_east_asian_font_selection();
+    test_max_height();
+    test_vertical_order();
+    test_GetCharWidth32();
+    test_fake_bold_font();
+    test_bitmap_font_glyph_index();
 
     /* These tests should be last test until RemoveFontResource
      * is properly implemented.
index 3b9f734..65374ea 100755 (executable)
@@ -121,7 +121,7 @@ static DWORD WINAPI thread_proc(void *param)
     DWORD status;
     struct hgdiobj_event *hgdiobj_event = param;
 
-    hgdiobj_event->hdc = CreateDC("display", NULL, NULL, NULL);
+    hgdiobj_event->hdc = CreateDCA("display", NULL, NULL, NULL);
     ok(hgdiobj_event->hdc != NULL, "CreateDC error %u\n", GetLastError());
 
     hgdiobj_event->hgdiobj1 = CreatePen(PS_DASHDOTDOT, 17, RGB(1, 2, 3));
@@ -134,7 +134,7 @@ static DWORD WINAPI thread_proc(void *param)
     status = WaitForSingleObject(hgdiobj_event->stop_event, INFINITE);
     ok(status == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", GetLastError());
 
-    ok(!GetObject(hgdiobj_event->hgdiobj1, sizeof(lp), &lp), "GetObject should fail\n");
+    ok(!GetObjectA(hgdiobj_event->hgdiobj1, sizeof(lp), &lp), "GetObject should fail\n");
 
     ok(!GetDeviceCaps(hgdiobj_event->hdc, TECHNOLOGY), "GetDeviceCaps(TECHNOLOGY) should fail\n");
 
@@ -151,9 +151,9 @@ static void test_thread_objects(void)
     DWORD status;
     BOOL bRet;
 
-    hgdiobj_event.stop_event = CreateEvent(NULL, 0, 0, NULL);
+    hgdiobj_event.stop_event = CreateEventA(NULL, 0, 0, NULL);
     ok(hgdiobj_event.stop_event != NULL, "CreateEvent error %u\n", GetLastError());
-    hgdiobj_event.ready_event = CreateEvent(NULL, 0, 0, NULL);
+    hgdiobj_event.ready_event = CreateEventA(NULL, 0, 0, NULL);
     ok(hgdiobj_event.ready_event != NULL, "CreateEvent error %u\n", GetLastError());
 
     hthread = CreateThread(NULL, 0, thread_proc, &hgdiobj_event, 0, &tid);
@@ -162,7 +162,7 @@ static void test_thread_objects(void)
     status = WaitForSingleObject(hgdiobj_event.ready_event, INFINITE);
     ok(status == WAIT_OBJECT_0, "WaitForSingleObject error %u\n", GetLastError());
 
-    ret = GetObject(hgdiobj_event.hgdiobj1, sizeof(lp), &lp);
+    ret = GetObjectA(hgdiobj_event.hgdiobj1, sizeof(lp), &lp);
     ok(ret == sizeof(lp), "GetObject error %u\n", GetLastError());
     ok(lp.lopnStyle == PS_DASHDOTDOT, "wrong pen style %d\n", lp.lopnStyle);
     ok(lp.lopnWidth.x == 17, "wrong pen width.y %d\n", lp.lopnWidth.x);
@@ -249,7 +249,7 @@ static void test_GetCurrentObject(void)
     hobj = GetCurrentObject(hdc, OBJ_BITMAP);
     ok(hobj == hbmp, "OBJ_BITMAP is wrong: %p\n", hobj);
 
-    assert(GetObject(hbrush, sizeof(lb), &lb) == sizeof(lb));
+    assert(GetObjectA(hbrush, sizeof(lb), &lb) == sizeof(lb));
     hpen = ExtCreatePen(PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_SQUARE | PS_JOIN_BEVEL,
                         10, &lb, 0, NULL);
     assert(hpen != 0);
index 497d900..019524d 100644 (file)
@@ -4434,13 +4434,6 @@ static void test_pack_NPEXTLOGPEN(void)
     TEST_TARGET_ALIGN(NPEXTLOGPEN, 8)
 }
 
-static void test_pack_OLDFONTENUMPROC(void)
-{
-    /* OLDFONTENUMPROC */
-    TEST_TYPE_SIZE   (OLDFONTENUMPROC, 8)
-    TEST_TYPE_ALIGN  (OLDFONTENUMPROC, 8)
-}
-
 static void test_pack_OLDFONTENUMPROCA(void)
 {
     /* OLDFONTENUMPROCA */
@@ -10964,13 +10957,6 @@ static void test_pack_NPEXTLOGPEN(void)
     TEST_TARGET_ALIGN(NPEXTLOGPEN, 4)
 }
 
-static void test_pack_OLDFONTENUMPROC(void)
-{
-    /* OLDFONTENUMPROC */
-    TEST_TYPE_SIZE   (OLDFONTENUMPROC, 4)
-    TEST_TYPE_ALIGN  (OLDFONTENUMPROC, 4)
-}
-
 static void test_pack_OLDFONTENUMPROCA(void)
 {
     /* OLDFONTENUMPROCA */
@@ -13386,7 +13372,6 @@ static void test_pack(void)
     test_pack_NEWTEXTMETRICEXW();
     test_pack_NEWTEXTMETRICW();
     test_pack_NPEXTLOGPEN();
-    test_pack_OLDFONTENUMPROC();
     test_pack_OLDFONTENUMPROCA();
     test_pack_OLDFONTENUMPROCW();
     test_pack_OUTLINETEXTMETRICA();
index 4850c29..b8dd8ee 100644 (file)
@@ -32,7 +32,7 @@ static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
 static DWORD (WINAPI *pGetLayout)(HDC hdc);
 static INT (WINAPI *pGetRandomRgn)(HDC hDC, HRGN hRgn, INT iCode);
 static BOOL (WINAPI *pGetTransform)(HDC, DWORD, XFORM *);
-static DWORD (WINAPI *pSetVirtualResolution)(HDC, DWORD, DWORD, DWORD, DWORD);
+static BOOL (WINAPI *pSetVirtualResolution)(HDC, DWORD, DWORD, DWORD, DWORD);
 
 #define rough_match(got, expected) (abs( MulDiv( (got) - (expected), 1000, (expected) )) <= 5)
 
@@ -513,7 +513,7 @@ static void test_isotropic_mapping(void)
 static void test_setvirtualresolution(void)
 {
     HDC hdc = CreateICA("DISPLAY", NULL, NULL, NULL);
-    DWORD r;
+    BOOL r;
     INT horz_res = GetDeviceCaps(hdc, HORZRES);
     INT horz_size = GetDeviceCaps(hdc, HORZSIZE);
     INT log_pixels_x = GetDeviceCaps(hdc, LOGPIXELSX);
index e10a72d..aae5995 100755 (executable)
@@ -2724,7 +2724,7 @@ static HENHMETAFILE create_converted_emf(const METAFILEPICT *mfp)
     UINT size;
     LPBYTE pBits;
 
-    hdcMf = CreateMetaFile(NULL);
+    hdcMf = CreateMetaFileA(NULL);
     ok(hdcMf != NULL, "CreateMetaFile failed with error %d\n", GetLastError());
     ret = LineTo(hdcMf, (INT)LINE_X, (INT)LINE_Y);
     ok(ret, "LineTo failed with error %d\n", GetLastError());
@@ -2904,7 +2904,7 @@ static void test_SetWinMetaFileBits(void)
   HDC dc;
   LONG diffx, diffy;
 
-  wmfDC = CreateMetaFile(NULL);
+  wmfDC = CreateMetaFileA(NULL);
   ok(wmfDC != NULL, "CreateMetaFile failed\n");
   if (!wmfDC) return;
 
@@ -3251,7 +3251,7 @@ static void test_gdiis(void)
     HMODULE hgdi32;
 
     /* resolve all the functions */
-    hgdi32 = GetModuleHandle("gdi32");
+    hgdi32 = GetModuleHandleA("gdi32.dll");
     pGdiIsMetaPrintDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaPrintDC");
     pGdiIsMetaFileDC = (void*) GetProcAddress(hgdi32, "GdiIsMetaFileDC");
     pGdiIsPlayMetafileDC = (void*) GetProcAddress(hgdi32, "GdiIsPlayMetafileDC");
@@ -3268,7 +3268,7 @@ static void test_gdiis(void)
     ok(!pGdiIsPlayMetafileDC(NULL), "isplaymetafile with NULL parameter\n");
 
     /* try with a metafile */
-    hmfDC = CreateMetaFile(NULL);
+    hmfDC = CreateMetaFileA(NULL);
     ok(!pGdiIsMetaPrintDC(hmfDC), "ismetaprint on metafile\n");
     ok(pGdiIsMetaFileDC(hmfDC), "ismetafile on metafile\n");
     ok(!pGdiIsPlayMetafileDC(hmfDC), "isplaymetafile on metafile\n");
index ebdc4e4..f95c0d3 100644 (file)
@@ -96,7 +96,7 @@ static void test_DIB_PAL_COLORS(void) {
     getColor = GetPixel( memhdc, 0, 0 );
     ok( getColor == chkColor, "getColor=%08X\n", (UINT)getColor );
 
-    /* Test with a invalid DIBINDEX to DIB_PAL_COLORS */
+    /* Test with an invalid DIBINDEX to DIB_PAL_COLORS */
     setColor = DIBINDEX( 12 );
     SetPixel( memhdc, 0, 0, setColor );
     chkColor = RGB( 0, 0, 0 );
@@ -162,10 +162,10 @@ static void test_halftone_palette(void)
     ok( count == 256 || broken(count <= 20), /* nt 4 */
         "wrong size %u\n", count );
 
-    /* first and last 10 match the default palette */
+    /* first and last 8 match the default palette */
     if (count >= 20)
     {
-        for (i = 0; i < 10; i++)
+        for (i = 0; i < 8; i++)
         {
             ok( entries[i].peRed   == defpal[i].peRed &&
                 entries[i].peGreen == defpal[i].peGreen &&
@@ -175,7 +175,7 @@ static void test_halftone_palette(void)
                 entries[i].peRed, entries[i].peGreen, entries[i].peBlue, entries[i].peFlags,
                 defpal[i].peRed, defpal[i].peGreen, defpal[i].peBlue );
         }
-        for (i = count - 10; i < count; i++)
+        for (i = count - 8; i < count; i++)
         {
             int idx = i - count + 20;
             ok( entries[i].peRed   == defpal[idx].peRed &&
index 8399b19..0b350bc 100644 (file)
@@ -270,7 +270,8 @@ static void test_widenpath(void)
     HDC hdc = GetDC(0);
     HPEN greenPen, narrowPen;
     POINT pnt[6];
-    INT nSize, ret;
+    INT nSize;
+    BOOL ret;
 
     /* Create a pen to be used in WidenPath */
     greenPen = CreatePen(PS_SOLID, 10, RGB(0,0,0));
index ed7927a..43f00d8 100644 (file)
@@ -95,7 +95,7 @@ static void test_logpen(void)
 
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp), &lp);
+        size = GetObjectW(hpen, sizeof(lp), &lp);
         ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
 
         ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
@@ -114,30 +114,30 @@ static void test_logpen(void)
         ok(obj_type == OBJ_PEN, "wrong object type %u\n", obj_type);
 
         /* check what's the real size of the object */
-        size = GetObject(hpen, 0, NULL);
+        size = GetObjectW(hpen, 0, NULL);
         ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
 
         /* ask for truncated data */
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
+        size = GetObjectW(hpen, sizeof(lp.lopnStyle), &lp);
         ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
 
         /* see how larger buffer sizes are handled */
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp) * 4, &lp);
+        size = GetObjectW(hpen, sizeof(lp) * 4, &lp);
         ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
 
         /* see how larger buffer sizes are handled */
         memset(&elp, 0xb0, sizeof(elp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(elp) * 2, &elp);
+        size = GetObjectW(hpen, sizeof(elp) * 2, &elp);
         ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
 
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp), &lp);
+        size = GetObjectW(hpen, sizeof(lp), &lp);
         ok(size == sizeof(lp), "GetObject returned %d, error %d\n", size, GetLastError());
 
         ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
@@ -147,13 +147,14 @@ static void test_logpen(void)
 
         memset(&elp, 0xb0, sizeof(elp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(elp), &elp);
+        size = GetObjectW(hpen, sizeof(elp), &elp);
 
         /* for some reason XP differentiates PS_NULL here */
         if (pen[i].style == PS_NULL)
         {
             ok(hpen == GetStockObject(NULL_PEN), "hpen should be a stock NULL_PEN\n");
-            ok(size == sizeof(EXTLOGPEN), "GetObject returned %d, error %d\n", size, GetLastError());
+            ok(size == offsetof(EXTLOGPEN, elpStyleEntry[1]), "GetObject returned %d, error %d\n",
+                size, GetLastError());
             ok(elp.elpPenStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, elp.elpPenStyle);
             ok(elp.elpWidth == 0, "expected 0, got %u\n", elp.elpWidth);
             ok(elp.elpColor == pen[i].ret_color, "expected %08x, got %08x\n", pen[i].ret_color, elp.elpColor);
@@ -230,7 +231,7 @@ static void test_logpen(void)
 
         /* check what's the real size of the object */
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, 0, NULL);
+        size = GetObjectW(hpen, 0, NULL);
         switch (pen[i].style)
         {
         case PS_NULL:
@@ -239,12 +240,12 @@ static void test_logpen(void)
             break;
 
         case PS_USERSTYLE:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry[2] ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry[2] ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             break;
 
         default:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             break;
         }
@@ -252,13 +253,13 @@ static void test_logpen(void)
         /* ask for truncated data */
         memset(&elp, 0xb0, sizeof(elp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(elp.elpPenStyle), &elp);
+        size = GetObjectW(hpen, sizeof(elp.elpPenStyle), &elp);
         ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
 
         /* see how larger buffer sizes are handled */
         memset(elp_buffer, 0xb0, sizeof(elp_buffer));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(elp_buffer), elp_buffer);
+        size = GetObjectW(hpen, sizeof(elp_buffer), elp_buffer);
         switch (pen[i].style)
         {
         case PS_NULL:
@@ -274,15 +275,15 @@ static void test_logpen(void)
             memset(&elp, 0xb0, sizeof(elp));
             memset(&unset_hatch, 0xb0, sizeof(unset_hatch));
             SetLastError(0xdeadbeef);
-            size = GetObject(hpen, sizeof(elp), &elp);
-            ok(size == sizeof(EXTLOGPEN),
+            size = GetObjectW(hpen, sizeof(elp), &elp);
+            ok(size == offsetof(EXTLOGPEN, elpStyleEntry[1]),
                 "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == unset_hatch, "expected 0xb0b0b0b0, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 0xb0b0b0b0, "expected 0xb0b0b0b0, got %x\n", ext_pen->elpNumEntries);
             break;
 
         case PS_USERSTYLE:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry[2] ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry[2] ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 2, "expected 0, got %x\n", ext_pen->elpNumEntries);
@@ -291,7 +292,7 @@ static void test_logpen(void)
             break;
 
         default:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 0, "expected 0, got %x\n", ext_pen->elpNumEntries);
@@ -340,7 +341,7 @@ test_geometric_pens:
             ok(obj_type == OBJ_EXTPEN, "wrong object type %u\n", obj_type);
 
         /* check what's the real size of the object */
-        size = GetObject(hpen, 0, NULL);
+        size = GetObjectW(hpen, 0, NULL);
         switch (pen[i].style)
         {
         case PS_NULL:
@@ -349,12 +350,12 @@ test_geometric_pens:
             break;
 
         case PS_USERSTYLE:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry[2] ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry[2] ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             break;
 
         default:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             break;
         }
@@ -362,12 +363,12 @@ test_geometric_pens:
         /* ask for truncated data */
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp.lopnStyle), &lp);
+        size = GetObjectW(hpen, sizeof(lp.lopnStyle), &lp);
         ok(!size, "GetObject should fail: size %d, error %d\n", size, GetLastError());
 
         memset(&lp, 0xb0, sizeof(lp));
         SetLastError(0xdeadbeef);
-        size = GetObject(hpen, sizeof(lp), &lp);
+        size = GetObjectW(hpen, sizeof(lp), &lp);
         /* for some reason XP differentiates PS_NULL here */
         if (pen[i].style == PS_NULL)
         {
@@ -385,18 +386,18 @@ test_geometric_pens:
         memset(elp_buffer, 0xb0, sizeof(elp_buffer));
         SetLastError(0xdeadbeef);
         /* buffer is too small for user styles */
-        size = GetObject(hpen, sizeof(EXTLOGPEN), elp_buffer);
+        size = GetObjectW(hpen, offsetof(EXTLOGPEN, elpStyleEntry[1]), elp_buffer);
         switch (pen[i].style)
         {
         case PS_NULL:
-            ok(size == sizeof(EXTLOGPEN),
+            ok(size == offsetof(EXTLOGPEN, elpStyleEntry[1]),
                 "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == 0, "expected 0, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 0, "expected 0, got %x\n", ext_pen->elpNumEntries);
 
             /* for PS_NULL it also works this way */
             SetLastError(0xdeadbeef);
-            size = GetObject(hpen, sizeof(elp_buffer), &lp);
+            size = GetObjectW(hpen, sizeof(elp_buffer), &lp);
             ok(size == sizeof(LOGPEN),
                 "GetObject returned %d, error %d\n", size, GetLastError());
             ok(lp.lopnStyle == pen[i].ret_style, "expected %u, got %u\n", pen[i].ret_style, lp.lopnStyle);
@@ -408,8 +409,8 @@ test_geometric_pens:
         case PS_USERSTYLE:
             ok(!size /*&& GetLastError() == ERROR_INVALID_PARAMETER*/,
                "GetObject should fail: size %d, error %d\n", size, GetLastError());
-            size = GetObject(hpen, sizeof(elp_buffer), elp_buffer);
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry[2] ),
+            size = GetObjectW(hpen, sizeof(elp_buffer), elp_buffer);
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry[2] ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 2, "expected 0, got %x\n", ext_pen->elpNumEntries);
@@ -418,7 +419,7 @@ test_geometric_pens:
             break;
 
         default:
-            ok(size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ),
+            ok(size == offsetof( EXTLOGPEN, elpStyleEntry ),
                "GetObject returned %d, error %d\n", size, GetLastError());
             ok(ext_pen->elpHatch == HS_CROSS, "expected HS_CROSS, got %p\n", (void *)ext_pen->elpHatch);
             ok(ext_pen->elpNumEntries == 0, "expected 0, got %x\n", ext_pen->elpNumEntries);
@@ -511,12 +512,8 @@ static void test_ps_userstyle(void)
     LOGBRUSH lb;
     HPEN pen;
     INT size, i;
-
-    struct
-    {
-        EXTLOGPEN elp;
-        DWORD style_data[15];
-    } ext_pen;
+    char buffer[offsetof(EXTLOGPEN, elpStyleEntry) + 16 * sizeof(DWORD)];
+    EXTLOGPEN *ext_pen = (EXTLOGPEN *)buffer;
 
     lb.lbColor = 0x00ff0000;
     lb.lbStyle = BS_SOLID;
@@ -561,18 +558,18 @@ static void test_ps_userstyle(void)
     pen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 50, &lb, 16, style);
     ok(pen != 0, "ExtCreatePen should not fail\n");
 
-    size = GetObject(pen, sizeof(ext_pen), &ext_pen);
-    expect(FIELD_OFFSET(EXTLOGPEN,elpStyleEntry[16]), size);
+    size = GetObjectW(pen, sizeof(buffer), ext_pen);
+    ok(size == offsetof(EXTLOGPEN, elpStyleEntry[16]), "wrong size %d\n", size);
 
     for(i = 0; i < 16; i++)
-        expect(style[i], ext_pen.elp.elpStyleEntry[i]);
+        expect(style[i], ext_pen->elpStyleEntry[i]);
 
     DeleteObject(pen);
 }
 
 static void test_brush_pens(void)
 {
-    char buffer[sizeof(EXTLOGPEN) + 15 * sizeof(DWORD)];
+    char buffer[offsetof(EXTLOGPEN, elpStyleEntry) + 16 * sizeof(DWORD)];
     EXTLOGPEN *elp = (EXTLOGPEN *)buffer;
     LOGBRUSH lb;
     HPEN pen = 0;
@@ -604,8 +601,8 @@ static void test_brush_pens(void)
             lb.lbHatch = HS_CROSS;
             pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
             ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
-            size = GetObject( pen, sizeof(buffer), elp );
-            ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
+            size = GetObjectW( pen, sizeof(buffer), elp );
+            ok( size == offsetof( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
             ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
             ok( elp->elpBrushStyle == lb.lbStyle, "wrong brush style %x\n", elp->elpBrushStyle );
             ok( elp->elpColor == RGB(12,34,56), "wrong color %x\n", elp->elpColor );
@@ -616,7 +613,7 @@ static void test_brush_pens(void)
         case BS_NULL:
             pen = ExtCreatePen( PS_SOLID | PS_GEOMETRIC, 3, &lb, 0, NULL );
             ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
-            size = GetObject( pen, sizeof(buffer), elp );
+            size = GetObjectW( pen, sizeof(buffer), elp );
             ok( size == sizeof(LOGPEN), "wrong size %u\n", size );
             ok( ((LOGPEN *)elp)->lopnStyle == PS_NULL,
                 "wrong pen style %x\n", ((LOGPEN *)elp)->lopnStyle );
@@ -629,8 +626,8 @@ static void test_brush_pens(void)
             lb.lbHatch = (ULONG_PTR)bmp;
             pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
             ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
-            size = GetObject( pen, sizeof(buffer), elp );
-            ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
+            size = GetObjectW( pen, sizeof(buffer), elp );
+            ok( size == offsetof( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
             ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
             ok( elp->elpBrushStyle == BS_PATTERN, "wrong brush style %x\n", elp->elpBrushStyle );
             ok( elp->elpColor == 0, "wrong color %x\n", elp->elpColor );
@@ -644,8 +641,8 @@ static void test_brush_pens(void)
             lb.lbHatch = lb.lbStyle == BS_DIBPATTERN ? (ULONG_PTR)hmem : (ULONG_PTR)info;
             pen = ExtCreatePen( PS_DOT | PS_GEOMETRIC, 3, &lb, 0, NULL );
             ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
-            size = GetObject( pen, sizeof(buffer), elp );
-            ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
+            size = GetObjectW( pen, sizeof(buffer), elp );
+            ok( size == offsetof( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
             ok( elp->elpPenStyle == (PS_DOT | PS_GEOMETRIC), "wrong pen style %x\n", elp->elpPenStyle );
             ok( elp->elpBrushStyle == BS_DIBPATTERNPT, "wrong brush style %x\n", elp->elpBrushStyle );
             ok( elp->elpColor == 0, "wrong color %x\n", elp->elpColor );
@@ -670,8 +667,8 @@ static void test_brush_pens(void)
         if (lb.lbStyle == BS_SOLID)
         {
             ok( pen != 0, "ExtCreatePen failed err %u\n", GetLastError() );
-            size = GetObject( pen, sizeof(buffer), elp );
-            ok( size == FIELD_OFFSET( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
+            size = GetObjectW( pen, sizeof(buffer), elp );
+            ok( size == offsetof( EXTLOGPEN, elpStyleEntry ), "wrong size %u\n", size );
             ok( elp->elpPenStyle == PS_DOT, "wrong pen style %x\n", elp->elpPenStyle );
             ok( elp->elpBrushStyle == BS_SOLID, "wrong brush style %x\n", elp->elpBrushStyle );
             ok( elp->elpColor == RGB(12,34,56), "wrong color %x\n", elp->elpColor );
index 34a3cdd..fdd95f6 100644 (file)
@@ -23,6 +23,8 @@
 /* @makedep: wine_test.ttf */
 wine_test.ttf RCDATA wine_test.ttf
 
+/* @makedep: wine_vdmx.ttf */
+wine_vdmx.ttf RCDATA wine_vdmx.ttf
 
 /* @makedep: vertical.ttf */
 vertical.ttf RCDATA vertical.ttf
index 370d1a1..86be6ef 100644 (file)
@@ -1,10 +1,7 @@
 /* Automatically generated file; DO NOT EDIT!! */
 
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
 #define STANDALONE
-#include "wine/test.h"
+#include <wine/test.h>
 
 extern void func_bitmap(void);
 extern void func_brush(void);
index 9ec5f04..9d08524 100644 (file)
@@ -1,46 +1,46 @@
 SplineFontDB: 3.0
-FontName: mplus-1p-regular
-FullName: M+ 1p regular
-FamilyName: M+ 1p regular
-Weight: Book
-Copyright: Copyright(c) 2011 M+ FONTS PROJECT
-Version: 1.044
+FontName: WineTestVertical
+FullName: WineTestVertical
+FamilyName: WineTestVertical
+Weight: Regular
+Copyright: Copyright(c) 2013 Wine Project
+Version: 1.055
 ItalicAngle: 0
 UnderlinePosition: -100
 UnderlineWidth: 50
 Ascent: 860
 Descent: 140
-sfntRevision: 0x00010b43
+sfntRevision: 0x00010e14
 LayerCount: 2
 Layer: 0 1 "Back"  1
 Layer: 1 1 "Fore"  0
-NeedsXUIDChange: 1
-XUID: [1021 311 1688707159 7641229]
+HasVMetrics: 1
+XUID: [1021 564 53499222 16482262]
 FSType: 0
 OS2Version: 1
 OS2_WeightWidthSlopeOnly: 0
 OS2_UseTypoMetrics: 1
 CreationTime: 1314095750
-ModificationTime: 1323339383
+ModificationTime: 1368817482
 PfmFamily: 17
 TTFWeight: 400
 TTFWidth: 5
 LineGap: 90
 VLineGap: 0
-Panose: 2 11 5 2 2 2 3 2 2 7
-OS2TypoAscent: 0
-OS2TypoAOffset: 1
-OS2TypoDescent: 0
-OS2TypoDOffset: 1
+Panose: 2 11 5 9 2 2 3 2 2 7
+OS2TypoAscent: 860
+OS2TypoAOffset: 0
+OS2TypoDescent: -140
+OS2TypoDOffset: 0
 OS2TypoLinegap: 90
-OS2WinAscent: 0
-OS2WinAOffset: 1
-OS2WinDescent: -23
-OS2WinDOffset: 1
-HheadAscent: 0
-HheadAOffset: 1
-HheadDescent: 23
-HheadDOffset: 1
+OS2WinAscent: 1075
+OS2WinAOffset: 0
+OS2WinDescent: 320
+OS2WinDOffset: 0
+HheadAscent: 1075
+HheadAOffset: 0
+HheadDescent: -320
+HheadDOffset: 0
 OS2SubXSize: 650
 OS2SubYSize: 700
 OS2SubXOff: 0
@@ -51,110 +51,812 @@ OS2SupXOff: 0
 OS2SupYOff: 480
 OS2StrikeYSize: 49
 OS2StrikeYPos: 258
-OS2FamilyClass: 2054
+OS2FamilyClass: 2057
 OS2Vendor: 'M+  '
-OS2CodePages: 601201bf.dff70000
-OS2UnicodeRanges: e1000aff.4a47fdfb.02000012.00000000
-Lookup: 4 0 1 "kana semi-voiced lookup"  {"kana semi-voiced table"  } ['ccmp' ('kana' <'dflt' > ) 'liga' ('kana' <'dflt' > ) ]
+OS2CodePages: 4012019f.dfd70000
+OS2UnicodeRanges: e00002ff.4a47fdeb.00000012.00000000
 Lookup: 1 0 0 "gsubvert"  {"j-vert"  } ['vert' ('cyrl' <'dflt' > 'grek' <'dflt' > 'hani' <'dflt' > 'kana' <'JAN ' 'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 4 0 1 "ligalookup01"  {"ligalookup01 subtable"  } ['liga' ('cyrl' <'dflt' > 'grek' <'dflt' > 'hani' <'dflt' > 'kana' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 4 0 0 "ccmplookup01"  {"ccmplookup01 subtable"  } ['ccmp' ('hani' <'dflt' > 'kana' <'JAN ' 'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 4 0 0 "ccmplookup02"  {"ccmplookup02 subtable"  } ['ccmp' ('cyrl' <'dflt' > 'grek' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 1 0 0 "SingleSubstitutionlookupDotless"  {"SingleSubstitutionlookupDotless subtable"  } []
-Lookup: 6 0 0 "ccmplookup03"  {"ccmplookup03 contextual 0"  "ccmplookup03 contextual 1"  "ccmplookup03 contextual 2"  } ['ccmp' ('cyrl' <'dflt' > 'grek' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 258 0 0 "kerning pairs"  {"kp"  } ['kern' ('latn' <'dflt' > ) ]
-Lookup: 262 4 0 "mkmklookup1"  {"mkmklookup1 subtable"  } ['mkmk' ('DFLT' <'dflt' > 'cyrl' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 260 4 0 "marklookup2"  {"marklookup2 subtable"  } ['mark' ('DFLT' <'dflt' > 'cyrl' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 260 4 0 "marklookup1"  {"marklookup1 subtable"  } ['mark' ('DFLT' <'dflt' > 'cyrl' <'dflt' > 'grek' <'dflt' > 'latn' <'dflt' > ) ]
-Lookup: 262 4 0 "mkmklookup2"  {"mkmklookup2 subtable"  } ['mkmk' ('DFLT' <'dflt' > 'cyrl' <'dflt' > 'latn' <'dflt' > ) ]
+MarkAttachClasses: 1
 DEI: 91125
-ChainSub2: coverage "ccmplookup03 contextual 2"  0 0 0 1
- 1 0 3
-  Coverage: 19 i j uni0249 uni03F3
-  FCoverage: 271 uni0316 uni0317 uni0318 uni0319 uni031C uni031D uni031E uni031F uni0320 uni0321 uni0322 uni0324 uni0325 uni0326 uni0327 uni0328 uni0329 uni032A uni032B uni032C uni032D uni032E uni032F uni0330 uni0331 uni0332 uni0333 uni0339 uni033A uni033B uni033C uni0345 uni0347 uni0353
-  FCoverage: 271 uni0316 uni0317 uni0318 uni0319 uni031C uni031D uni031E uni031F uni0320 uni0321 uni0322 uni0324 uni0325 uni0326 uni0327 uni0328 uni0329 uni032A uni032B uni032C uni032D uni032E uni032F uni0330 uni0331 uni0332 uni0333 uni0339 uni033A uni033B uni033C uni0345 uni0347 uni0353
-  FCoverage: 307 gravecomb acutecomb uni0302 tildecomb uni0304 uni0305 uni0306 uni0307 uni0308 hookabovecomb uni030A uni030B uni030C uni030D uni030E uni030F uni0310 uni0311 uni0312 uni0313 uni0314 uni033D uni033E uni033F uni0340 uni0341 uni0342 uni0343 uni0344 uni0346 uni0351 uni0352 uni0357 uni0483 uni0484 uni0485 uni0486
+TtTable: prep
+PUSHW_1
+ 511
+SCANCTRL
+PUSHB_1
  1
-  SeqLookup: 0 "SingleSubstitutionlookupDotless" 
-EndFPST
-ChainSub2: coverage "ccmplookup03 contextual 1"  0 0 0 1
- 1 0 2
-  Coverage: 19 i j uni0249 uni03F3
-  FCoverage: 271 uni0316 uni0317 uni0318 uni0319 uni031C uni031D uni031E uni031F uni0320 uni0321 uni0322 uni0324 uni0325 uni0326 uni0327 uni0328 uni0329 uni032A uni032B uni032C uni032D uni032E uni032F uni0330 uni0331 uni0332 uni0333 uni0339 uni033A uni033B uni033C uni0345 uni0347 uni0353
-  FCoverage: 307 gravecomb acutecomb uni0302 tildecomb uni0304 uni0305 uni0306 uni0307 uni0308 hookabovecomb uni030A uni030B uni030C uni030D uni030E uni030F uni0310 uni0311 uni0312 uni0313 uni0314 uni033D uni033E uni033F uni0340 uni0341 uni0342 uni0343 uni0344 uni0346 uni0351 uni0352 uni0357 uni0483 uni0484 uni0485 uni0486
+SCANTYPE
+SVTCA[y-axis]
+MPPEM
+PUSHB_1
+ 8
+LT
+IF
+PUSHB_2
  1
-  SeqLookup: 0 "SingleSubstitutionlookupDotless" 
-EndFPST
-ChainSub2: coverage "ccmplookup03 contextual 0"  0 0 0 1
- 1 0 1
-  Coverage: 19 i j uni0249 uni03F3
-  FCoverage: 307 gravecomb acutecomb uni0302 tildecomb uni0304 uni0305 uni0306 uni0307 uni0308 hookabovecomb uni030A uni030B uni030C uni030D uni030E uni030F uni0310 uni0311 uni0312 uni0313 uni0314 uni033D uni033E uni033F uni0340 uni0341 uni0342 uni0343 uni0344 uni0346 uni0351 uni0352 uni0357 uni0483 uni0484 uni0485 uni0486
  1
-  SeqLookup: 0 "SingleSubstitutionlookupDotless" 
-EndFPST
-MacFeat: 0 0 0
-MacName: 0 0 24 "All Typographic Features"
-MacName: 0 1 24 "Fonctions typographiques"
-MacName: 0 2 33 "Alle typografischen M\232glichkeiten"
-MacName: 0 3 21 "Funzioni Tipografiche"
-MacName: 0 4 28 "Alle typografische kenmerken"
-MacSetting: 0
-MacName: 0 0 17 "All Type Features"
-MacName: 0 1 31 "Toutes fonctions typographiques"
-MacName: 0 2 23 "Alle Auszeichnungsarten"
-MacName: 0 3 17 "Tutte le Funzioni"
-MacName: 0 4 18 "Alle typekenmerken"
-MacFeat: 1 0 0
-MacName: 0 0 9 "Ligatures"
-MacName: 0 1 9 "Ligatures"
-MacName: 0 2 9 "Ligaturen"
-MacName: 0 3 8 "Legature"
-MacName: 0 4 9 "Ligaturen"
-MacSetting: 2
-MacName: 0 0 16 "Common Ligatures"
-MacName: 0 1 18 "Ligatures Usuelles"
-MacName: 0 2 17 "Normale Ligaturen"
-MacName: 0 3 19 "Legature pi\235 Comuni"
-MacName: 0 4 28 "Gemeenschappelijke Ligaturen"
-EndMacFeatures
-TtTable: prep
-PUSHW_2
- 511
+INSTCTRL
+EIF
+PUSHB_2
+ 70
+ 6
+CALL
+IF
+POP
+PUSHB_1
+ 16
+EIF
+MPPEM
+PUSHB_1
+ 20
+GT
+IF
+POP
+PUSHB_1
+ 128
+EIF
+SCVTCI
+PUSHB_1
+ 6
+CALL
+NOT
+IF
+EIF
+PUSHB_1
+ 20
+CALL
+EndTTInstrs
+TtTable: fpgm
+PUSHB_1
  0
-SCANTYPE
-SCANCTRL
+FDEF
+PUSHB_1
+ 0
+SZP0
+MPPEM
+PUSHB_1
+ 42
+LT
+IF
+PUSHB_1
+ 74
+SROUND
+EIF
+PUSHB_1
+ 0
+SWAP
+MIAP[rnd]
+RTG
+PUSHB_1
+ 6
+CALL
+IF
+RTDG
+EIF
+MPPEM
+PUSHB_1
+ 42
+LT
+IF
+RDTG
+EIF
+DUP
+MDRP[rp0,rnd,grey]
+PUSHB_1
+ 1
+SZP0
+MDAP[no-rnd]
+RTG
+ENDF
+PUSHB_1
+ 1
+FDEF
+DUP
+MDRP[rp0,min,white]
+PUSHB_1
+ 12
+CALL
+ENDF
+PUSHB_1
+ 2
+FDEF
+MPPEM
+GT
+IF
+RCVT
+SWAP
+EIF
+POP
+ENDF
+PUSHB_1
+ 3
+FDEF
+ROUND[Black]
+RTG
+DUP
+PUSHB_1
+ 64
+LT
+IF
+POP
+PUSHB_1
+ 64
+EIF
+ENDF
+PUSHB_1
+ 4
+FDEF
+PUSHB_1
+ 6
+CALL
+IF
+POP
+SWAP
+POP
+ROFF
+IF
+MDRP[rp0,min,rnd,black]
+ELSE
+MDRP[min,rnd,black]
+EIF
+ELSE
+MPPEM
+GT
+IF
+IF
+MIRP[rp0,min,rnd,black]
+ELSE
+MIRP[min,rnd,black]
+EIF
+ELSE
+SWAP
+POP
+PUSHB_1
+ 5
+CALL
+IF
+PUSHB_1
+ 70
+SROUND
+EIF
+IF
+MDRP[rp0,min,rnd,black]
+ELSE
+MDRP[min,rnd,black]
+EIF
+EIF
+EIF
+RTG
+ENDF
+PUSHB_1
+ 5
+FDEF
+GFV
+NOT
+AND
+ENDF
+PUSHB_1
+ 6
+FDEF
+PUSHB_2
+ 34
+ 1
+GETINFO
+LT
+IF
+PUSHB_1
+ 32
+GETINFO
+NOT
+NOT
+ELSE
+PUSHB_1
+ 0
+EIF
+ENDF
+PUSHB_1
+ 7
+FDEF
+PUSHB_2
+ 36
+ 1
+GETINFO
+LT
+IF
+PUSHB_1
+ 64
+GETINFO
+NOT
+NOT
+ELSE
+PUSHB_1
+ 0
+EIF
+ENDF
+PUSHB_1
+ 8
+FDEF
+SRP2
+SRP1
+DUP
+IP
+MDAP[rnd]
+ENDF
+PUSHB_1
+ 9
+FDEF
+DUP
+RDTG
+PUSHB_1
+ 6
+CALL
+IF
+MDRP[rnd,grey]
+ELSE
+MDRP[min,rnd,black]
+EIF
+DUP
+PUSHB_1
+ 3
+CINDEX
+MD[grid]
+SWAP
+DUP
+PUSHB_1
+ 4
+MINDEX
+MD[orig]
+PUSHB_1
+ 0
+LT
+IF
+ROLL
+NEG
+ROLL
+SUB
+DUP
+PUSHB_1
+ 0
+LT
+IF
+SHPIX
+ELSE
+POP
+POP
+EIF
+ELSE
+ROLL
+ROLL
+SUB
+DUP
+PUSHB_1
+ 0
+GT
+IF
+SHPIX
+ELSE
+POP
+POP
+EIF
+EIF
+RTG
+ENDF
+PUSHB_1
+ 10
+FDEF
+PUSHB_1
+ 6
+CALL
+IF
+POP
+SRP0
+ELSE
+SRP0
+POP
+EIF
+ENDF
+PUSHB_1
+ 11
+FDEF
+DUP
+MDRP[rp0,white]
+PUSHB_1
+ 12
+CALL
+ENDF
+PUSHB_1
+ 12
+FDEF
+DUP
+MDAP[rnd]
+PUSHB_1
+ 7
+CALL
+NOT
+IF
+DUP
+DUP
+GC[orig]
+SWAP
+GC[cur]
+SUB
+ROUND[White]
+DUP
+IF
+DUP
+ABS
+DIV
+SHPIX
+ELSE
+POP
+POP
+EIF
+ELSE
+POP
+EIF
+ENDF
+PUSHB_1
+ 13
+FDEF
+SRP2
+SRP1
+DUP
+DUP
+IP
+MDAP[rnd]
+DUP
+ROLL
+DUP
+GC[orig]
+ROLL
+GC[cur]
+SUB
+SWAP
+ROLL
+DUP
+ROLL
+SWAP
+MD[orig]
+PUSHB_1
+ 0
+LT
+IF
+SWAP
+PUSHB_1
+ 0
+GT
+IF
+PUSHB_1
+ 64
+SHPIX
+ELSE
+POP
+EIF
+ELSE
+SWAP
+PUSHB_1
+ 0
+LT
+IF
+PUSHB_1
+ 64
+NEG
+SHPIX
+ELSE
+POP
+EIF
+EIF
+ENDF
+PUSHB_1
+ 14
+FDEF
+PUSHB_1
+ 6
+CALL
+IF
+RTDG
+MDRP[rp0,rnd,white]
+RTG
+POP
+POP
+ELSE
+DUP
+MDRP[rp0,rnd,white]
+ROLL
+MPPEM
+GT
+IF
+DUP
+ROLL
+SWAP
+MD[grid]
+DUP
+PUSHB_1
+ 0
+NEQ
+IF
+SHPIX
+ELSE
+POP
+POP
+EIF
+ELSE
+POP
+POP
+EIF
+EIF
+ENDF
+PUSHB_1
+ 15
+FDEF
+SWAP
+DUP
+MDRP[rp0,rnd,white]
+DUP
+MDAP[rnd]
+PUSHB_1
+ 7
+CALL
+NOT
+IF
+SWAP
+DUP
+IF
+MPPEM
+GTEQ
+ELSE
+POP
+PUSHB_1
+ 1
+EIF
+IF
+ROLL
+PUSHB_1
+ 4
+MINDEX
+MD[grid]
+SWAP
+ROLL
+SWAP
+DUP
+ROLL
+MD[grid]
+ROLL
+SWAP
+SUB
+SHPIX
+ELSE
+POP
+POP
+POP
+POP
+EIF
+ELSE
+POP
+POP
+POP
+POP
+POP
+EIF
+ENDF
+PUSHB_1
+ 16
+FDEF
+DUP
+MDRP[rp0,min,white]
+PUSHB_1
+ 18
+CALL
+ENDF
+PUSHB_1
+ 17
+FDEF
+DUP
+MDRP[rp0,white]
+PUSHB_1
+ 18
+CALL
+ENDF
+PUSHB_1
+ 18
+FDEF
+DUP
+MDAP[rnd]
+PUSHB_1
+ 7
+CALL
+NOT
+IF
+DUP
+DUP
+GC[orig]
+SWAP
+GC[cur]
+SUB
+ROUND[White]
+ROLL
+DUP
+GC[orig]
+SWAP
+GC[cur]
+SWAP
+SUB
+ROUND[White]
+ADD
+DUP
+IF
+DUP
+ABS
+DIV
+SHPIX
+ELSE
+POP
+POP
+EIF
+ELSE
+POP
+POP
+EIF
+ENDF
+PUSHB_1
+ 19
+FDEF
+DUP
+ROLL
+DUP
+ROLL
+SDPVTL[orthog]
+DUP
+PUSHB_1
+ 3
+CINDEX
+MD[orig]
+ABS
+SWAP
+ROLL
+SPVTL[orthog]
+PUSHB_1
+ 32
+LT
+IF
+ALIGNRP
+ELSE
+MDRP[grey]
+EIF
+ENDF
+PUSHB_1
+ 20
+FDEF
+PUSHB_4
+ 0
+ 64
+ 1
+ 64
+WS
+WS
+SVTCA[x-axis]
+MPPEM
+PUSHW_1
+ 4096
+MUL
+SVTCA[y-axis]
+MPPEM
+PUSHW_1
+ 4096
+MUL
+DUP
+ROLL
+DUP
+ROLL
+NEQ
+IF
+DUP
+ROLL
+DUP
+ROLL
+GT
+IF
+SWAP
+DIV
+DUP
+PUSHB_1
+ 0
+SWAP
+WS
+ELSE
+DIV
+DUP
+PUSHB_1
+ 1
+SWAP
+WS
+EIF
+DUP
+PUSHB_1
+ 64
+GT
+IF
+PUSHB_3
+ 0
+ 32
+ 0
+RS
+MUL
+WS
+PUSHB_3
+ 1
+ 32
+ 1
+RS
+MUL
+WS
+PUSHB_1
+ 32
+MUL
+PUSHB_1
+ 25
+NEG
+JMPR
+POP
+EIF
+ELSE
+POP
+POP
+EIF
+ENDF
+PUSHB_1
+ 21
+FDEF
+PUSHB_1
+ 1
+RS
+MUL
+SWAP
+PUSHB_1
+ 0
+RS
+MUL
+SWAP
+ENDF
 EndTTInstrs
+ShortTable: cvt  6
+  -220
+  0
+  520
+  730
+  33
+  633
+EndShort
 ShortTable: maxp 16
   1
   0
-  6439
-  216
-  18
-  0
-  0
+  7223
+  192
+  22
+  102
+  11
   2
+  1
+  2
+  22
   0
-  0
-  0
-  0
-  4
-  0
-  0
-  0
+  256
+  46
+  1
+  1
 EndShort
-LangName: 1033 "" "@WineTestVertical" "Regular" "FontForge 2.0 : M+- 1p regular : 2-11-2011" "" "" "" "" "" "" "" "http://mplus-fonts.sourceforge.jp" "" "" "" "" "M+- 1p" "regular" 
-GaspTable: 1 65535 2
+LangName: 1033 "" "" "" "FontForge 2.0 : WineTestVertical: 11-3-2013" "" "Version 1.055" "" "" "" "" "" "http://www.winehq.com" "" "" "" "" "WineTestVertical" "regular"
+GaspTable: 1 65535 2 0
 Encoding: UnicodeFull
 UnicodeInterp: none
 NameList: Adobe Glyph List
-DisplaySize: -24
+DisplaySize: -36
 AntiAlias: 1
 FitToEm: 1
-AnchorClass2: "TopMark"  "mkmklookup1 subtable" "Bottom"  "marklookup2 subtable" "Top"  "marklookup1 subtable" "BottomMark"  "mkmklookup2 subtable" 
-BeginChars: 1114185 2
+WinInfo: 1114120 23 9
+BeginPrivate: 0
+EndPrivate
+TeXData: 1 0 0 346030 173015 115343 0 1048576 115343 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
+BeginChars: 1114326 14
+
+StartChar: .notdef
+Encoding: 1114112 -1 0
+Width: 364
+Flags: W
+TtInstrs:
+PUSHB_2
+ 1
+ 0
+MDAP[rnd]
+ALIGNRP
+PUSHB_3
+ 7
+ 4
+ 4
+MIRP[min,rnd,black]
+SHP[rp2]
+PUSHB_2
+ 6
+ 5
+MDRP[rp0,min,rnd,grey]
+ALIGNRP
+PUSHB_3
+ 3
+ 2
+ 4
+MIRP[min,rnd,black]
+SHP[rp2]
+SVTCA[y-axis]
+PUSHB_2
+ 3
+ 0
+MDAP[rnd]
+ALIGNRP
+PUSHB_3
+ 5
+ 4
+ 4
+MIRP[min,rnd,black]
+SHP[rp2]
+PUSHB_3
+ 7
+ 6
+ 5
+MIRP[rp0,min,rnd,grey]
+ALIGNRP
+PUSHB_3
+ 1
+ 2
+ 4
+MIRP[min,rnd,black]
+SHP[rp2]
+EndTTInstrs
+LayerCount: 2
+Fore
+SplineSet
+33 0 m 1,0,-1
+ 33 666 l 1,1,-1
+ 298 666 l 1,2,-1
+ 298 0 l 1,3,-1
+ 33 0 l 1,0,-1
+66 33 m 1,4,-1
+ 265 33 l 1,5,-1
+ 265 633 l 1,6,-1
+ 66 633 l 1,7,-1
+ 66 33 l 1,4,-1
+EndSplineSet
+EndChar
+
+StartChar: glyph1
+Encoding: 1114113 -1 1
+Width: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: glyph2
+Encoding: 1114114 -1 2
+Width: 333
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: W
+Encoding: 87 87 3
+Width: 500
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+415 0 m 1,0,-1
+ 257 725 l 1,1,-1
+ 85 0 l 1,2,-1
+ 415 0 l 1,0,-1
+EndSplineSet
+EndChar
 
 StartChar: twodotenleader
-Encoding: 8229 8229 0
+Encoding: 8229 8229 4
 Width: 1000
 GlyphClass: 2
 Flags: W
@@ -175,8 +877,41 @@ EndSplineSet
 Substitution2: "j-vert" twodotenleader.vert
 EndChar
 
-StartChar: twodotenleader.vert
-Encoding: 1114131 -1 1
+StartChar: uni3042
+Encoding: 12354 12354 5
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+133 677 m 1,0,-1
+ 133 613 l 1,1,-1
+ 487 0 l 5,2,-1
+ 867 613 l 1,3,-1
+ 867 677 l 1,4,-1
+ 133 677 l 1,0,-1
+EndSplineSet
+EndChar
+
+StartChar: uni5EAD
+Encoding: 24237 24237 6
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+21 -21 m 1,0,1
+876 741.3 m 1,2,-1
+ 122 815.3 l 1,3,-1
+ 122 683.3 l 1,4,-1
+ 876 741.3 l 1,2,-1
+EndSplineSet
+EndChar
+
+StartChar: uniFE30
+Encoding: 65072 65072 7
 Width: 1000
 GlyphClass: 2
 Flags: W
@@ -195,5 +930,112 @@ SplineSet
  453 40 l 1,4,-1
 EndSplineSet
 EndChar
+
+StartChar: uniFF37
+Encoding: 65335 65335 8
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+945 641 m 17,0,-1
+ 519 797 l 5,1,-1
+ 97 637 l 9,2,-1
+ 527 0 l 25,3,-1
+ 945 641 l 17,0,-1
+EndSplineSet
+EndChar
+
+StartChar: uniFF5B
+Encoding: 65371 65371 9
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+892 755 m 17,0,-1
+ 428 392 l 1,1,-1
+ 428 328 l 1,2,-1
+ 892 -35 l 9,3,-1
+ 892 755 l 17,0,-1
+EndSplineSet
+Substitution2: "j-vert" uniFF5B.vert
+EndChar
+
+StartChar: uniFF9D
+Encoding: 65437 65437 10
+Width: 500
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+467 623 m 17,0,-1
+ 397 637 l 1,1,-1
+ 77 322.2 l 17,2,-1
+ 100 -10 l 1,3,-1
+ 467 623 l 17,0,-1
+EndSplineSet
+EndChar
+
+StartChar: twodotenleader.vert
+Encoding: 1114272 -1 11
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+453 40 m 1,0,-1
+ 453 180 l 1,1,-1
+ 547 180 l 1,2,-1
+ 547 40 l 1,3,-1
+ 453 40 l 1,0,-1
+453 540 m 1,4,-1
+ 453 680 l 1,5,-1
+ 547 680 l 1,6,-1
+ 547 540 l 1,7,-1
+ 453 540 l 1,4,-1
+EndSplineSet
+EndChar
+
+StartChar: uni3041.vert
+Encoding: 1114293 -1 12
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+522 557 m 1,0,-1
+ 875 557 l 1,1,-1
+ 875 617 l 1,2,-1
+ 522 617 l 1,3,-1
+ 522 715 l 1,4,-1
+ 454 715 l 1,5,-1
+ 454 617 l 1,6,-1
+ 285 617 l 1,7,-1
+ 285 557 l 1,8,-1
+ 522 557 l 1,0,-1
+EndSplineSet
+EndChar
+
+StartChar: uniFF5B.vert
+Encoding: 1114321 -1 13
+Width: 1000
+GlyphClass: 2
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+543 340 m 25,0,-1
+ 29 -30 l 25,1,-1
+ 971 -32 l 1,2,-1
+ 521 112 l 1,3,-1
+ 543 340 l 25,0,-1
+EndSplineSet
+EndChar
 EndChars
 EndSplineFont
index c48b3c1..0fc0779 100644 (file)
Binary files a/rostests/winetests/gdi32/vertical.ttf and b/rostests/winetests/gdi32/vertical.ttf differ
index 5adf7cf..4c19377 100644 (file)
@@ -20,7 +20,7 @@ OS2Version: 2
 OS2_WeightWidthSlopeOnly: 0
 OS2_UseTypoMetrics: 1
 CreationTime: 1288336343
-ModificationTime: 1352483620
+ModificationTime: 1366465321
 PfmFamily: 17
 TTFWeight: 500
 TTFWidth: 5
@@ -32,10 +32,10 @@ OS2TypoAOffset: 1
 OS2TypoDescent: 0
 OS2TypoDOffset: 1
 OS2TypoLinegap: 184
-OS2WinAscent: 0
-OS2WinAOffset: 1
-OS2WinDescent: 0
-OS2WinDOffset: 1
+OS2WinAscent: 1638
+OS2WinAOffset: 0
+OS2WinDescent: 410
+OS2WinDOffset: 0
 HheadAscent: 0
 HheadAOffset: 1
 HheadDescent: 0
@@ -78,15 +78,17 @@ ShortTable: maxp 16
   0
 EndShort
 LangName: 1033 "" "" "" "Wine : wine_test : 4-11-2010"
-GaspTable: 1 65535 2
+GaspTable: 1 65535 2 0
 Encoding: UnicodeBmp
 UnicodeInterp: none
 NameList: Adobe Glyph List
 DisplaySize: -24
 AntiAlias: 1
 FitToEm: 1
-WinInfo: 65 65 19
-BeginChars: 65539 5
+WinInfo: 48 16 4
+BeginPrivate: 0
+EndPrivate
+BeginChars: 65539 7
 
 StartChar: .notdef
 Encoding: 65536 -1 0
@@ -178,10 +180,10 @@ LayerCount: 2
 EndChar
 
 StartChar: dieresis
-Encoding: 168 168 0
+Encoding: 168 168 4
 Width: 1000
 VWidth: 0
-Flags: HW
+Flags: W
 LayerCount: 2
 Fore
 SplineSet
@@ -201,5 +203,43 @@ SplineSet
  310.707 834.805 310.707 834.805 254.492 773.213 c 1,12,13
 EndSplineSet
 EndChar
+
+StartChar: A
+Encoding: 65 65 5
+Width: 1000
+VWidth: 0
+Flags: WO
+LayerCount: 2
+Fore
+SplineSet
+459 1258 m 29,0,-1
+ 462 1639 l 5,1,-1
+ 389 1638 l 5,2,-1
+ 492 1815 l 5,3,-1
+ 609 1638.5 l 5,4,-1
+ 531 1637.5 l 5,5,-1
+ 523 1258 l 5,6,-1
+ 459 1258 l 29,0,-1
+EndSplineSet
+EndChar
+
+StartChar: D
+Encoding: 68 68 6
+Width: 1000
+VWidth: 0
+Flags: WO
+LayerCount: 2
+Fore
+SplineSet
+461 -30.7998 m 29,0,-1
+ 464 -411.8 l 5,1,-1
+ 391 -410.8 l 5,2,-1
+ 494 -587.8 l 5,3,-1
+ 611 -411.3 l 5,4,-1
+ 533 -410.3 l 5,5,-1
+ 525 -30.7998 l 5,6,-1
+ 461 -30.7998 l 29,0,-1
+EndSplineSet
+EndChar
 EndChars
 EndSplineFont
index 1e546eb..0868802 100644 (file)
Binary files a/rostests/winetests/gdi32/wine_test.ttf and b/rostests/winetests/gdi32/wine_test.ttf differ
diff --git a/rostests/winetests/gdi32/wine_vdmx.sfd b/rostests/winetests/gdi32/wine_vdmx.sfd
new file mode 100644 (file)
index 0000000..d1ccad6
--- /dev/null
@@ -0,0 +1,271 @@
+SplineFontDB: 3.0
+FontName: wine_vdmx
+FullName: wine_vdmx
+FamilyName: wine_vdmx
+Weight: Medium
+Copyright: Copyright (c) 2010 Dmitry Timoshkov
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -170
+UnderlineWidth: 130
+Ascent: 1638
+Descent: 410
+sfntRevision: 0x00010000
+LayerCount: 2
+Layer: 0 1 "Back" 1
+Layer: 1 1 "Fore" 0
+XUID: [1021 905 592216984 1247726]
+FSType: 0
+OS2Version: 2
+OS2_WeightWidthSlopeOnly: 0
+OS2_UseTypoMetrics: 1
+PfmFamily: 33
+TTFWeight: 400
+TTFWidth: 5
+LineGap: 0
+VLineGap: 0
+Panose: 2 11 6 4 3 5 4 4 2 4
+OS2TypoAscent: 1566
+OS2TypoAOffset: 0
+OS2TypoDescent: -423
+OS2TypoDOffset: 0
+OS2TypoLinegap: 59
+OS2WinAscent: 2049
+OS2WinAOffset: 0
+OS2WinDescent: 423
+OS2WinDOffset: 0
+HheadAscent: 2049
+HheadAOffset: 0
+HheadDescent: -423
+HheadDOffset: 0
+OS2SubXSize: 1331
+OS2SubYSize: 1433
+OS2SubXOff: 0
+OS2SubYOff: 2861
+OS2SupXSize: 1331
+OS2SupYSize: 1433
+OS2SupXOff: 0
+OS2SupYOff: 983
+OS2StrikeYSize: 102
+OS2StrikeYPos: 530
+OS2Vendor: 'Wine'
+OS2CodePages: 00000001.00000000
+OS2UnicodeRanges: 00000001.00000000.00000000.00000000
+MarkAttachClasses: 1
+DEI: 91125
+ShortTable: cvt  2
+  68
+  1297
+EndShort
+ShortTable: maxp 16
+  1
+  0
+  4
+  8
+  2
+  0
+  0
+  2
+  0
+  1
+  1
+  0
+  64
+  46
+  0
+  0
+EndShort
+TtfTable: VDMX 1504
+!!!!"!!*'#!<E0/!;Hj"!!iQ1s8E!)!"&])!"&]5s8E!+!"8i+!"8i:s8;p,!"Ju,!"Ju>s82j-
+!"f2.!"],Bs82j/!##>0!"o8Fs82j1!#>P3!#,DKs82j3!#P\5!#>PNs82j5!#Yb5!#P\Ss7u^5
+!#kn6!#bhVs7u^7!$2+9!#tt[s7u^9!$;1:!$2+_s7u^;!$VC=!$D7bs7lX<!$_I=!$VCgs7lX>
+!%%[@!$hOks7lX@!%7gA!%%[os7cRA!%@mB!%7gss7ZLB!%\*D!%It"s7ZLD!%n6F!%\+&s7QFE
+!&"<F!%n7*s7QFG!&=NI!&+C.s7QFI!&OZK!&=O2s7QFK!&jlN!&O[6s7H@L!&srN!&ag:s7H@N
+!'(#O!&ss?s7?:O!'L;R!'1*Cs7?:Q!'UAS!'C6Fs7?:S!'gMU!'UBJs764T!($YU!'gNOs7-.U
+!(6eW!($ZRs7-.W!(R"Z!(6fWs7-.Y!([([!(HrZs7-.[!)!:^!([)_s7$(\!)3F^!(m5cs6p"]
+!)<L_!)*Afs6p"_!)NXa!)<Mks6p"a!)ijd!)NYos6p"c!*'!e!)`ers6fqd!*9-g!)rr"s6fqf
+!*B3h!*0)&s6]kg!*]Ej!*B5*s6Teh!*oQk!*TA.s6Tej!+,]m!*fM1s6K_k!+5cm!+#Y7s6K_m
+!+Pup!+5e:s6K_o!+c,q!+Gq=s6BYp!+u8s!+Z(Bs6BYr!,;K!!+l4Fs69Ss!,DQ!!,)@Ks69Su
+!,V]#!,;LNs69T"!,hi$!,MXQs60N#!-/&'!,_dWs60N%!-A2)!,qpZs6'H&!-J8)!-/'_s6'H(
+!-eJ,!-A3ds6'H*!.+\.!-S?gs5sB+!.4b/!-eKls5sB-!.Ot2!."Wos5j<.!.Y%2!.4cts5j<0
+!.t75!.Fp#s5j<2!/1C6!.Y'&s5a63!/:I7!.k3*s5a65!/^a;!/(?/s5X06!/gg;!/:K3s5X08
+!/pm<!/LW7s5X0:!07*>!/^c:s5O*;!0I6@!/po?s5O*=!0dHB!0.&Cs5F$>!0mNC!0@2Gs5F$@
+!1!TD!0R>Ks5F$B!1ElG!0dJOs5<sC!1NrH!1!VSs5<sE!1a)I!13bWs53mF!1s5K!1En\s53mH
+!20AM!1X%_s53mJ!2KSO!1j1cs5*gK!2TYP!2'=gs5*gM!2okS!29Iks5!aN!3-"T!2KUps5!aP
+!36(U!2]ass5!aR!3H4V!2on"s4m[S!3cFY!3-%'s4dUT!3lLY!3?1*s4dUV!42^\!3Q=/s4dUX
+!4;d]!3cI3s4dUZ!4W!_!3uU6s4[O[!4i-a!42a;s4[O]!4r3b!4Dm>s4RI^!5/?c!4W$Ds4RI`
+!5JQf!4i0Gs4RIb!5\]g!5&<Js4ICc!5nii!58HPs4@=d!65&k!5JTTs4@=f!6G2m!5\`Xs4@=h
+!6Y>o!5nl\s4@=j!6kJp!6,#_s477k!7(Vq!6>/es4.1l!7:bs!6P;hs4.1n!7Lnu!6bGls4.1p
+!7_&"!6tSqs4.1r!8%8$!71_ts4%+s!8.>%!7Cl#s4%+u!8@J'!7V#'s3q&!!8[\)!7h/,s3q&#
+!8db)!8%;0s3gu$!9*t,!87G3s3gu&!94%,!8IS7s3^o'!9O7/!8[_<s3^o)!9aC1!8mk@s3^o+
+!9jI2!9+"Ds3^o-!:0[4!9=.Hs3Ui.!:Bg6!9O:Ls3Ui0!:Km6!9aFPs3Lc1!:g*9!9sRTs3Lc3
+!:p0:!:0^Xs3Lc5!;?H=!:Bj\s3:W5!;HN=!:U!`s3:W7!;QT>!:g-ds3:W9!;ulB!;$9hs3:W;
+!<)rC!;6Els31Q<!<<)D!;HQps3(K=!<N5E!;Z]ts3(K?!<`AG!;lj#s3(KA!=&SJ!<*!'s3(KC
+!=/YK
+EndTtf
+LangName: 1033 "" "" "" "Wine : wine_vdmx : 4-11-2010"
+GaspTable: 1 65535 2 0
+Encoding: UnicodeBmp
+UnicodeInterp: none
+NameList: Adobe Glyph List
+DisplaySize: -24
+AntiAlias: 1
+FitToEm: 1
+WinInfo: 48 16 4
+BeginPrivate: 0
+EndPrivate
+BeginChars: 65539 7
+
+StartChar: .notdef
+Encoding: 65536 -1 0
+Width: 748
+Flags: W
+TtInstrs:
+PUSHB_2
+ 1
+ 0
+MDAP[rnd]
+ALIGNRP
+PUSHB_3
+ 7
+ 4
+ 0
+MIRP[min,rnd,black]
+SHP[rp2]
+PUSHB_2
+ 6
+ 5
+MDRP[rp0,min,rnd,grey]
+ALIGNRP
+PUSHB_3
+ 3
+ 2
+ 0
+MIRP[min,rnd,black]
+SHP[rp2]
+SVTCA[y-axis]
+PUSHB_2
+ 3
+ 0
+MDAP[rnd]
+ALIGNRP
+PUSHB_3
+ 5
+ 4
+ 0
+MIRP[min,rnd,black]
+SHP[rp2]
+PUSHB_3
+ 7
+ 6
+ 1
+MIRP[rp0,min,rnd,grey]
+ALIGNRP
+PUSHB_3
+ 1
+ 2
+ 0
+MIRP[min,rnd,black]
+SHP[rp2]
+EndTTInstrs
+LayerCount: 2
+Fore
+SplineSet
+68 0 m 1,0,-1
+ 68 1365 l 1,1,-1
+ 612 1365 l 1,2,-1
+ 612 0 l 1,3,-1
+ 68 0 l 1,0,-1
+136 68 m 1,4,-1
+ 544 68 l 1,5,-1
+ 544 1297 l 1,6,-1
+ 136 1297 l 1,7,-1
+ 136 68 l 1,4,-1
+EndSplineSet
+EndChar
+
+StartChar: .null
+Encoding: 65537 -1 1
+Width: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: nonmarkingreturn
+Encoding: 65538 -1 2
+Width: 682
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: exclam
+Encoding: 33 33 3
+Width: 0
+Flags: W
+LayerCount: 2
+EndChar
+
+StartChar: dieresis
+Encoding: 168 168 4
+Width: 1000
+VWidth: 0
+Flags: W
+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
+
+StartChar: A
+Encoding: 65 65 5
+Width: 1000
+VWidth: 0
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+459 1258 m 29,0,-1
+ 462 1639 l 5,1,-1
+ 389 1638 l 5,2,-1
+ 492 1815 l 5,3,-1
+ 609 1638.5 l 5,4,-1
+ 531 1637.5 l 5,5,-1
+ 523 1258 l 5,6,-1
+ 459 1258 l 29,0,-1
+EndSplineSet
+EndChar
+
+StartChar: D
+Encoding: 68 68 6
+Width: 1000
+VWidth: 0
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+461 -30.7998 m 29,0,-1
+ 464 -411.8 l 5,1,-1
+ 391 -410.8 l 5,2,-1
+ 494 -587.8 l 5,3,-1
+ 611 -411.3 l 5,4,-1
+ 533 -410.3 l 5,5,-1
+ 525 -30.7998 l 5,6,-1
+ 461 -30.7998 l 29,0,-1
+EndSplineSet
+EndChar
+EndChars
+EndSplineFont
diff --git a/rostests/winetests/gdi32/wine_vdmx.ttf b/rostests/winetests/gdi32/wine_vdmx.ttf
new file mode 100644 (file)
index 0000000..882e2c3
Binary files /dev/null and b/rostests/winetests/gdi32/wine_vdmx.ttf differ