[gdiplus_winetest]
authorChristoph von Wittich <christoph_vw@reactos.org>
Sun, 3 Jan 2010 10:54:40 +0000 (10:54 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sun, 3 Jan 2010 10:54:40 +0000 (10:54 +0000)
sync gdiplus_winetest with wine 1.1.35

svn path=/trunk/; revision=44906

rostests/winetests/gdiplus/brush.c
rostests/winetests/gdiplus/customlinecap.c
rostests/winetests/gdiplus/font.c
rostests/winetests/gdiplus/graphics.c
rostests/winetests/gdiplus/graphicspath.c
rostests/winetests/gdiplus/image.c
rostests/winetests/gdiplus/pathiterator.c
rostests/winetests/gdiplus/pen.c

index b6fbe30..0ee4dd4 100644 (file)
@@ -310,9 +310,9 @@ static void test_gradientgetrect(void)
     memset(&rectf, 0, sizeof(GpRectF));
     status = GdipGetLineRect(brush, &rectf);
     expect(Ok, status);
     memset(&rectf, 0, sizeof(GpRectF));
     status = GdipGetLineRect(brush, &rectf);
     expect(Ok, status);
-    todo_wine expectf(-5.0, rectf.X);
+    expectf(-5.0, rectf.X);
     expectf(0.0, rectf.Y);
     expectf(0.0, rectf.Y);
-    todo_wine expectf(10.0, rectf.Width);
+    expectf(10.0, rectf.Width);
     expectf(10.0, rectf.Height);
     status = GdipDeleteBrush((GpBrush*)brush);
     /* horizontal gradient */
     expectf(10.0, rectf.Height);
     status = GdipDeleteBrush((GpBrush*)brush);
     /* horizontal gradient */
@@ -324,9 +324,9 @@ static void test_gradientgetrect(void)
     status = GdipGetLineRect(brush, &rectf);
     expect(Ok, status);
     expectf(0.0, rectf.X);
     status = GdipGetLineRect(brush, &rectf);
     expect(Ok, status);
     expectf(0.0, rectf.X);
-    todo_wine expectf(-5.0, rectf.Y);
+    expectf(-5.0, rectf.Y);
     expectf(10.0, rectf.Width);
     expectf(10.0, rectf.Width);
-    todo_wine expectf(10.0, rectf.Height);
+    expectf(10.0, rectf.Height);
     status = GdipDeleteBrush((GpBrush*)brush);
     /* slope = -1 */
     pt1.X = pt1.Y = 0.0;
     status = GdipDeleteBrush((GpBrush*)brush);
     /* slope = -1 */
     pt1.X = pt1.Y = 0.0;
@@ -395,8 +395,11 @@ static void test_lineblend(void)
     int i;
     const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f};
     const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
     int i;
     const REAL factors[5] = {0.0f, 0.1f, 0.5f, 0.9f, 1.0f};
     const REAL positions[5] = {0.0f, 0.2f, 0.5f, 0.8f, 1.0f};
+    const REAL two_positions[2] = {0.0f, 1.0f};
+    const ARGB colors[5] = {0xff0000ff, 0xff00ff00, 0xff00ffff, 0xffff0000, 0xffffffff};
     REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
     REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
     REAL res_factors[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
     REAL res_positions[6] = {0.3f, 0.0f, 0.0f, 0.0f, 0.0f};
+    ARGB res_colors[6] = {0xdeadbeef, 0, 0, 0, 0};
 
     pt1.X = pt1.Y = 1.0;
     pt2.X = pt2.Y = 100.0;
 
     pt1.X = pt1.Y = 1.0;
     pt2.X = pt2.Y = 100.0;
@@ -489,6 +492,156 @@ static void test_lineblend(void)
     status = GdipGetLineBlend(brush, res_factors, res_positions, 1);
     expect(Ok, status);
 
     status = GdipGetLineBlend(brush, res_factors, res_positions, 1);
     expect(Ok, status);
 
+    status = GdipGetLinePresetBlendCount(NULL, &count);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlendCount(brush, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlendCount(brush, &count);
+    expect(Ok, status);
+    expect(0, count);
+
+    status = GdipGetLinePresetBlend(NULL, res_colors, res_positions, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, NULL, res_positions, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, NULL, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, -1);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 2);
+    expect(GenericError, status);
+
+    status = GdipSetLinePresetBlend(NULL, colors, positions, 5);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, NULL, positions, 5);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, NULL, 5);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, positions, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, positions, -1);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, positions, 1);
+    expect(InvalidParameter, status);
+
+    /* leave off the 0.0 position */
+    status = GdipSetLinePresetBlend(brush, &colors[1], &positions[1], 4);
+    expect(InvalidParameter, status);
+
+    /* leave off the 1.0 position */
+    status = GdipSetLinePresetBlend(brush, colors, positions, 4);
+    expect(InvalidParameter, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, positions, 5);
+    expect(Ok, status);
+
+    status = GdipGetLinePresetBlendCount(brush, &count);
+    expect(Ok, status);
+    expect(5, count);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 4);
+    expect(InsufficientBuffer, status);
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 5);
+    expect(Ok, status);
+
+    for (i=0; i<5; i++)
+    {
+        expect(colors[i], res_colors[i]);
+        expectf(positions[i], res_positions[i]);
+    }
+
+    status = GdipGetLinePresetBlend(brush, res_colors, res_positions, 6);
+    expect(Ok, status);
+
+    status = GdipSetLinePresetBlend(brush, colors, two_positions, 2);
+    expect(Ok, status);
+
+    status = GdipDeleteBrush((GpBrush*)brush);
+    expect(Ok, status);
+}
+
+static void test_linelinearblend(void)
+{
+    GpLineGradient *brush;
+    GpStatus status;
+    GpPointF pt1, pt2;
+    INT count=10;
+    REAL res_factors[3] = {0.3f};
+    REAL res_positions[3] = {0.3f};
+
+    status = GdipSetLineLinearBlend(NULL, 0.6, 0.8);
+    expect(InvalidParameter, status);
+
+    pt1.X = pt1.Y = 1.0;
+    pt2.X = pt2.Y = 100.0;
+    status = GdipCreateLineBrush(&pt1, &pt2, 0, 0, WrapModeTile, &brush);
+    expect(Ok, status);
+
+
+    status = GdipSetLineLinearBlend(brush, 0.6, 0.8);
+    expect(Ok, status);
+
+    status = GdipGetLineBlendCount(brush, &count);
+    expect(Ok, status);
+    expect(3, count);
+
+    status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
+    expect(Ok, status);
+    expectf(0.0, res_factors[0]);
+    expectf(0.0, res_positions[0]);
+    expectf(0.8, res_factors[1]);
+    expectf(0.6, res_positions[1]);
+    expectf(0.0, res_factors[2]);
+    expectf(1.0, res_positions[2]);
+
+
+    status = GdipSetLineLinearBlend(brush, 0.0, 0.8);
+    expect(Ok, status);
+
+    status = GdipGetLineBlendCount(brush, &count);
+    expect(Ok, status);
+    expect(2, count);
+
+    status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
+    expect(Ok, status);
+    expectf(0.8, res_factors[0]);
+    expectf(0.0, res_positions[0]);
+    expectf(0.0, res_factors[1]);
+    expectf(1.0, res_positions[1]);
+
+
+    status = GdipSetLineLinearBlend(brush, 1.0, 0.8);
+    expect(Ok, status);
+
+    status = GdipGetLineBlendCount(brush, &count);
+    expect(Ok, status);
+    expect(2, count);
+
+    status = GdipGetLineBlend(brush, res_factors, res_positions, 3);
+    expect(Ok, status);
+    expectf(0.0, res_factors[0]);
+    expectf(0.0, res_positions[0]);
+    expectf(0.8, res_factors[1]);
+    expectf(1.0, res_positions[1]);
+
     status = GdipDeleteBrush((GpBrush*)brush);
     expect(Ok, status);
 }
     status = GdipDeleteBrush((GpBrush*)brush);
     expect(Ok, status);
 }
@@ -515,6 +668,7 @@ START_TEST(brush)
     test_texturewrap();
     test_gradientgetrect();
     test_lineblend();
     test_texturewrap();
     test_gradientgetrect();
     test_lineblend();
+    test_linelinearblend();
 
     GdiplusShutdown(gdiplusToken);
 }
 
     GdiplusShutdown(gdiplusToken);
 }
index 78a8c70..218e46d 100644 (file)
@@ -59,8 +59,11 @@ static void test_constructor_destructor(void)
     stat = GdipDeleteCustomLineCap(custom);
     expect(Ok, stat);
     /* it's strange but native returns NotImplemented on stroke == NULL */
     stat = GdipDeleteCustomLineCap(custom);
     expect(Ok, stat);
     /* it's strange but native returns NotImplemented on stroke == NULL */
+    custom = NULL;
     stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 10.0, &custom);
     todo_wine expect(NotImplemented, stat);
     stat = GdipCreateCustomLineCap(path, NULL, LineCapFlat, 10.0, &custom);
     todo_wine expect(NotImplemented, stat);
+    todo_wine ok(custom == NULL, "Expected a failure on creation\n");
+    if(stat == Ok) GdipDeleteCustomLineCap(custom);
 
     GdipDeletePath(path2);
     GdipDeletePath(path);
 
     GdipDeletePath(path2);
     GdipDeletePath(path);
index 0da5b2f..7b95d4c 100644 (file)
@@ -31,14 +31,6 @@ static const WCHAR MicrosoftSansSerif[] = {'M','i','c','r','o','s','o','f','t','
 static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
 static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
 
 static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
 static const WCHAR CourierNew[] = {'C','o','u','r','i','e','r',' ','N','e','w','\0'};
 
-static const char *debugstr_w(LPCWSTR str)
-{
-   static char buf[1024];
-   WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
-   return buf;
-}
-
-
 static void test_createfont(void)
 {
     GpFontFamily* fontfamily = NULL, *fontfamily2;
 static void test_createfont(void)
 {
     GpFontFamily* fontfamily = NULL, *fontfamily2;
@@ -71,7 +63,7 @@ static void test_createfont(void)
     stat = GdipGetFamilyName(fontfamily2, familyname, 0);
     expect(Ok, stat);
     ok (lstrcmpiW(arial, familyname) == 0, "Expected arial, got %s\n",
     stat = GdipGetFamilyName(fontfamily2, familyname, 0);
     expect(Ok, stat);
     ok (lstrcmpiW(arial, familyname) == 0, "Expected arial, got %s\n",
-            debugstr_w(familyname));
+            wine_dbgstr_w(familyname));
     stat = GdipDeleteFontFamily(fontfamily2);
     expect(Ok, stat);
 
     stat = GdipDeleteFontFamily(fontfamily2);
     expect(Ok, stat);
 
@@ -201,6 +193,7 @@ todo_wine
 {
     stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
     expect (FontFamilyNotFound, stat);
 {
     stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
     expect (FontFamilyNotFound, stat);
+    if(stat == Ok) GdipDeleteFontFamily(family);
 }
 
     stat = GdipCreateFontFamilyFromName (arial, NULL, &family);
 }
 
     stat = GdipCreateFontFamilyFromName (arial, NULL, &family);
@@ -302,10 +295,9 @@ static void test_getgenerics (void)
     expect (Ok, stat);
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
     expect (Ok, stat);
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
-    ok ((lstrcmpiW(familyName, MicrosoftSansSerif) == 0) ||
-        (lstrcmpiW(familyName,MSSansSerif) == 0),
-        "Expected Microsoft Sans Serif or MS Sans Serif, got %s\n",
-        debugstr_w(familyName));
+    todo_wine ok ((lstrcmpiW(familyName, MicrosoftSansSerif) == 0),
+        "Expected Microsoft Sans Serif, got %s\n",
+        wine_dbgstr_w(familyName));
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 
@@ -320,7 +312,7 @@ serif:
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
     ok (lstrcmpiW(familyName, TimesNewRoman) == 0,
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
     ok (lstrcmpiW(familyName, TimesNewRoman) == 0,
-        "Expected Times New Roman, got %s\n", debugstr_w(familyName));
+        "Expected Times New Roman, got %s\n", wine_dbgstr_w(familyName));
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 
@@ -335,7 +327,7 @@ monospace:
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
     ok (lstrcmpiW(familyName, CourierNew) == 0,
     stat = GdipGetFamilyName (family, familyName, LANG_NEUTRAL);
     expect (Ok, stat);
     ok (lstrcmpiW(familyName, CourierNew) == 0,
-        "Expected Courier New, got %s\n", debugstr_w(familyName));
+        "Expected Courier New, got %s\n", wine_dbgstr_w(familyName));
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 }
     stat = GdipDeleteFontFamily (family);
     expect (Ok, stat);
 }
index 61143c6..45bd9f7 100644 (file)
@@ -137,8 +137,7 @@ static void test_save_restore(void)
     stat = GdipRestoreGraphics(graphics1, state_a);
     expect(Ok, stat);
     GdipGetInterpolationMode(graphics1, &mode);
     stat = GdipRestoreGraphics(graphics1, state_a);
     expect(Ok, stat);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
@@ -154,12 +153,10 @@ static void test_save_restore(void)
     expect(Ok, stat);
     GdipRestoreGraphics(graphics1, state_b);
     GdipGetInterpolationMode(graphics1, &mode);
     expect(Ok, stat);
     GdipRestoreGraphics(graphics1, state_b);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
@@ -176,16 +173,13 @@ static void test_save_restore(void)
     GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
     GdipRestoreGraphics(graphics1, state_b);
     GdipGetInterpolationMode(graphics1, &mode);
     GdipSetInterpolationMode(graphics1, InterpolationModeHighQualityBilinear);
     GdipRestoreGraphics(graphics1, state_b);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_c);
     GdipGetInterpolationMode(graphics1, &mode);
     GdipRestoreGraphics(graphics1, state_c);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
     GdipDeleteGraphics(graphics1);
 
     log_state(state_a, &state_log);
@@ -204,12 +198,10 @@ static void test_save_restore(void)
     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
     GdipSetInterpolationMode(graphics2, InterpolationModeNearestNeighbor);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     GdipRestoreGraphics(graphics2, state_b);
     GdipGetInterpolationMode(graphics2, &mode);
     GdipRestoreGraphics(graphics2, state_b);
     GdipGetInterpolationMode(graphics2, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipDeleteGraphics(graphics1);
     GdipDeleteGraphics(graphics2);
 
     GdipDeleteGraphics(graphics1);
     GdipDeleteGraphics(graphics2);
 
@@ -243,8 +235,6 @@ static void test_GdipDrawArc(void)
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
-    status = GdipCreateFromHDC(hdc, &graphics);
-    expect(Ok, status);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
@@ -289,8 +279,577 @@ static void test_GdipDrawArcI(void)
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
+    status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
+    expect(InvalidParameter, status);
+
+    /* successful case */
+    status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_BeginContainer2(void)
+{
+    GpMatrix *transform;
+    GpRectF clip;
+    REAL defClip[] = {5, 10, 15, 20};
+    REAL elems[6], defTrans[] = {1, 2, 3, 4, 5, 6};
+    GraphicsContainer cont1, cont2, cont3, cont4;
+    CompositingQuality compqual, defCompqual = CompositingQualityHighSpeed;
+    CompositingMode compmode, defCompmode = CompositingModeSourceOver;
+    InterpolationMode interp, defInterp = InterpolationModeHighQualityBicubic;
+    REAL scale, defScale = 17;
+    GpUnit unit, defUnit = UnitPixel;
+    PixelOffsetMode offsetmode, defOffsetmode = PixelOffsetModeHighSpeed;
+    SmoothingMode smoothmode, defSmoothmode = SmoothingModeAntiAlias;
+    UINT contrast, defContrast = 5;
+    TextRenderingHint texthint, defTexthint = TextRenderingHintAntiAlias;
+
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    HDC hdc = GetDC(0);
+
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    /* null graphics, null container */
+    status = GdipBeginContainer2(NULL, &cont1);
+    expect(InvalidParameter, status);
+
+    status = GdipBeginContainer2(graphics, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipEndContainer(NULL, cont1);
+    expect(InvalidParameter, status);
+
+    /* test all quality-related values */
+    GdipSetCompositingMode(graphics, defCompmode);
+    GdipSetCompositingQuality(graphics, defCompqual);
+    GdipSetInterpolationMode(graphics, defInterp);
+    GdipSetPageScale(graphics, defScale);
+    GdipSetPageUnit(graphics, defUnit);
+    GdipSetPixelOffsetMode(graphics, defOffsetmode);
+    GdipSetSmoothingMode(graphics, defSmoothmode);
+    GdipSetTextContrast(graphics, defContrast);
+    GdipSetTextRenderingHint(graphics, defTexthint);
+
+    status = GdipBeginContainer2(graphics, &cont1);
+    expect(Ok, status);
+
+    GdipSetCompositingMode(graphics, CompositingModeSourceCopy);
+    GdipSetCompositingQuality(graphics, CompositingQualityHighQuality);
+    GdipSetInterpolationMode(graphics, InterpolationModeBilinear);
+    GdipSetPageScale(graphics, 10);
+    GdipSetPageUnit(graphics, UnitDocument);
+    GdipSetPixelOffsetMode(graphics, PixelOffsetModeHalf);
+    GdipSetSmoothingMode(graphics, SmoothingModeNone);
+    GdipSetTextContrast(graphics, 7);
+    GdipSetTextRenderingHint(graphics, TextRenderingHintClearTypeGridFit);
+
+    status = GdipEndContainer(graphics, cont1);
+    expect(Ok, status);
+
+    GdipGetCompositingMode(graphics, &compmode);
+    ok(defCompmode == compmode, "Expected Compositing Mode to be restored to %d, got %d\n", defCompmode, compmode);
+
+    GdipGetCompositingQuality(graphics, &compqual);
+    ok(defCompqual == compqual, "Expected Compositing Quality to be restored to %d, got %d\n", defCompqual, compqual);
+
+    GdipGetInterpolationMode(graphics, &interp);
+    ok(defInterp == interp, "Expected Interpolation Mode to be restored to %d, got %d\n", defInterp, interp);
+
+    GdipGetPageScale(graphics, &scale);
+    ok(fabs(defScale - scale) < 0.0001, "Expected Page Scale to be restored to %f, got %f\n", defScale, scale);
+
+    GdipGetPageUnit(graphics, &unit);
+    ok(defUnit == unit, "Expected Page Unit to be restored to %d, got %d\n", defUnit, unit);
+
+    GdipGetPixelOffsetMode(graphics, &offsetmode);
+    ok(defOffsetmode == offsetmode, "Expected Pixel Offset Mode to be restored to %d, got %d\n", defOffsetmode, offsetmode);
+
+    GdipGetSmoothingMode(graphics, &smoothmode);
+    ok(defSmoothmode == smoothmode, "Expected Smoothing Mode to be restored to %d, got %d\n", defSmoothmode, smoothmode);
+
+    GdipGetTextContrast(graphics, &contrast);
+    ok(defContrast == contrast, "Expected Text Contrast to be restored to %d, got %d\n", defContrast, contrast);
+
+    GdipGetTextRenderingHint(graphics, &texthint);
+    ok(defTexthint == texthint, "Expected Text Hint to be restored to %d, got %d\n", defTexthint, texthint);
+
+    /* test world transform */
+    status = GdipBeginContainer2(graphics, &cont1);
+    expect(Ok, status);
+
+    GdipCreateMatrix2(defTrans[0], defTrans[1], defTrans[2], defTrans[3],
+            defTrans[4], defTrans[5], &transform);
+    GdipSetWorldTransform(graphics, transform);
+    GdipDeleteMatrix(transform);
+    transform = NULL;
+
+    status = GdipBeginContainer2(graphics, &cont2);
+    expect(Ok, status);
+
+    GdipCreateMatrix2(10, 20, 30, 40, 50, 60, &transform);
+    GdipSetWorldTransform(graphics, transform);
+    GdipDeleteMatrix(transform);
+    transform = NULL;
+
+    status = GdipEndContainer(graphics, cont2);
+    expect(Ok, status);
+
+    GdipCreateMatrix(&transform);
+    GdipGetWorldTransform(graphics, transform);
+    GdipGetMatrixElements(transform, elems);
+    ok(fabs(defTrans[0] - elems[0]) < 0.0001 &&
+            fabs(defTrans[1] - elems[1]) < 0.0001 &&
+            fabs(defTrans[2] - elems[2]) < 0.0001 &&
+            fabs(defTrans[3] - elems[3]) < 0.0001 &&
+            fabs(defTrans[4] - elems[4]) < 0.0001 &&
+            fabs(defTrans[5] - elems[5]) < 0.0001,
+            "Expected World Transform Matrix to be restored to [%f, %f, %f, %f, %f, %f], got [%f, %f, %f, %f, %f, %f]\n",
+            defTrans[0], defTrans[1], defTrans[2], defTrans[3], defTrans[4], defTrans[5],
+            elems[0], elems[1], elems[2], elems[3], elems[4], elems[5]);
+    GdipDeleteMatrix(transform);
+    transform = NULL;
+
+    status = GdipEndContainer(graphics, cont1);
+    expect(Ok, status);
+
+    /* test clipping */
+    status = GdipBeginContainer2(graphics, &cont1);
+    expect(Ok, status);
+
+    GdipSetClipRect(graphics, defClip[0], defClip[1], defClip[2], defClip[3], CombineModeReplace);
+
+    status = GdipBeginContainer2(graphics, &cont2);
+    expect(Ok, status);
+
+    GdipSetClipRect(graphics, 2, 4, 6, 8, CombineModeReplace);
+
+    status = GdipEndContainer(graphics, cont2);
+
+    GdipGetClipBounds(graphics, &clip);
+    ok(fabs(defClip[0] - clip.X) < 0.0001 &&
+            fabs(defClip[1] - clip.Y) < 0.0001 &&
+            fabs(defClip[2] - clip.Width) < 0.0001 &&
+            fabs(defClip[3] - clip.Height) < 0.0001,
+            "Expected Clipping Rectangle to be restored to [%f, %f, %f, %f], got [%f, %f, %f, %f]\n",
+            defClip[0], defClip[1], defClip[2], defClip[3],
+            clip.X, clip.Y, clip.Width, clip.Height);
+
+    status = GdipEndContainer(graphics, cont1);
+
+    /* nesting */
+    status = GdipBeginContainer2(graphics, &cont1);
+    expect(Ok, status);
+
+    status = GdipBeginContainer2(graphics, &cont2);
+    expect(Ok, status);
+
+    status = GdipBeginContainer2(graphics, &cont3);
+    expect(Ok, status);
+
+    status = GdipEndContainer(graphics, cont3);
+    expect(Ok, status);
+
+    status = GdipBeginContainer2(graphics, &cont4);
+    expect(Ok, status);
+
+    status = GdipEndContainer(graphics, cont4);
+    expect(Ok, status);
+
+    /* skip cont2 */
+    status = GdipEndContainer(graphics, cont1);
+    expect(Ok, status);
+
+    /* end an already-ended container */
+    status = GdipEndContainer(graphics, cont1);
+    expect(Ok, status);
+
+    GdipDeleteGraphics(graphics);
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawBezierI(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+
+    /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
+    expect(InvalidParameter, status);
+
+    /* successful case */
+    status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawCurve3(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+    GpPointF points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
+
+    /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawCurve3(NULL, NULL, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, NULL, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(NULL, pen, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurve3(graphics, pen, points, -1, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 0, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 1, 0, 0, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 3, 4, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid number of segments */
+    status = GdipDrawCurve3(graphics, pen, points, 3, 0, -1, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 3, 1, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 2, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, 1);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 3, 0, 2, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 2, 0, 1, -2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3(graphics, pen, points, 3, 1, 1, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawCurve3I(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+    GpPoint points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
+
+    /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawCurve3I(NULL, NULL, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(graphics, NULL, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(NULL, pen, points, 3, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurve3I(graphics, pen, points, -1, -1, -1, 1);
+    expect(OutOfMemory, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 0, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 1, 0, 0, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 3, 4, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid number of segments */
+    status = GdipDrawCurve3I(graphics, pen, points, 3, 0, -1, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 2, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 2, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, 1);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 3, 0, 2, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 2, 0, 1, -2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve3I(graphics, pen, points, 3, 1, 1, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawCurve2(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+    GpPointF points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
+
+    /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawCurve2(NULL, NULL, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2(graphics, NULL, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2(NULL, pen, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurve2(graphics, pen, points, -1, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2(graphics, pen, points, 0, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2(graphics, pen, points, 1, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurve2(graphics, pen, points, 2, 1);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2(graphics, pen, points, 3, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2(graphics, pen, points, 3, -2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2(graphics, pen, points, 3, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawCurve2I(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+    GpPoint points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
+
+    /* make a graphics object and pen object */
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
     status = GdipCreateFromHDC(hdc, &graphics);
     expect(Ok, status);
     status = GdipCreateFromHDC(hdc, &graphics);
     expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
+    expect(Ok, status);
+    ok(pen != NULL, "Expected pen to be initialized\n");
+
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawCurve2I(NULL, NULL, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2I(graphics, NULL, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2I(NULL, pen, points, 3, 1);
+    expect(InvalidParameter, status);
+
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurve2I(graphics, pen, points, -1, 1);
+    expect(OutOfMemory, status);
+
+    status = GdipDrawCurve2I(graphics, pen, points, 0, 1);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurve2I(graphics, pen, points, 1, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurve2I(graphics, pen, points, 2, 1);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2I(graphics, pen, points, 3, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2I(graphics, pen, points, 3, -2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve2I(graphics, pen, points, 3, 0);
+    expect(Ok, status);
+
+    GdipDeletePen(pen);
+    GdipDeleteGraphics(graphics);
+
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipDrawCurve(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpPen *pen = NULL;
+    HDC hdc = GetDC(0);
+    GpPointF points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
+
+    /* make a graphics object and pen object */
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
@@ -301,24 +860,31 @@ static void test_GdipDrawArcI(void)
     expect(Ok, status);
     ok(pen != NULL, "Expected pen to be initialized\n");
 
     expect(Ok, status);
     ok(pen != NULL, "Expected pen to be initialized\n");
 
-    /* InvalidParameter cases: null graphics, null pen, non-positive width, non-positive height */
-    status = GdipDrawArcI(NULL, NULL, 0, 0, 0, 0, 0, 0);
+    /* InvalidParameter cases: null graphics, null pen */
+    status = GdipDrawCurve(NULL, NULL, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
+    status = GdipDrawCurve(graphics, NULL, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
+    status = GdipDrawCurve(NULL, pen, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawArcI(graphics, pen, 0, 0, 1, 0, 0, 0);
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurve(graphics, pen, points, -1);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
+    status = GdipDrawCurve(graphics, pen, points, 0);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    /* successful case */
-    status = GdipDrawArcI(graphics, pen, 0, 0, 1, 1, 0, 0);
+    status = GdipDrawCurve(graphics, pen, points, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurve(graphics, pen, points, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurve(graphics, pen, points, 3);
     expect(Ok, status);
 
     GdipDeletePen(pen);
     expect(Ok, status);
 
     GdipDeletePen(pen);
@@ -327,16 +893,24 @@ static void test_GdipDrawArcI(void)
     ReleaseDC(0, hdc);
 }
 
     ReleaseDC(0, hdc);
 }
 
-static void test_GdipDrawBezierI(void)
+static void test_GdipDrawCurveI(void)
 {
     GpStatus status;
     GpGraphics *graphics = NULL;
     GpPen *pen = NULL;
     HDC hdc = GetDC(0);
 {
     GpStatus status;
     GpGraphics *graphics = NULL;
     GpPen *pen = NULL;
     HDC hdc = GetDC(0);
+    GpPoint points[3];
+
+    points[0].X = 0;
+    points[0].Y = 0;
+
+    points[1].X = 40;
+    points[1].Y = 20;
+
+    points[2].X = 10;
+    points[2].Y = 40;
 
     /* make a graphics object and pen object */
 
     /* make a graphics object and pen object */
-    status = GdipCreateFromHDC(hdc, &graphics);
-    expect(Ok, status);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
@@ -348,17 +922,30 @@ static void test_GdipDrawBezierI(void)
     ok(pen != NULL, "Expected pen to be initialized\n");
 
     /* InvalidParameter cases: null graphics, null pen */
     ok(pen != NULL, "Expected pen to be initialized\n");
 
     /* InvalidParameter cases: null graphics, null pen */
-    status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(NULL, NULL, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(graphics, NULL, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(NULL, pen, points, 3);
     expect(InvalidParameter, status);
 
     expect(InvalidParameter, status);
 
-    /* successful case */
-    status = GdipDrawBezierI(graphics, pen, 0, 0, 0, 0, 0, 0, 0, 0);
+    /* InvalidParameter cases: invalid count */
+    status = GdipDrawCurveI(graphics, pen, points, -1);
+    expect(OutOfMemory, status);
+
+    status = GdipDrawCurveI(graphics, pen, points, 0);
+    expect(InvalidParameter, status);
+
+    status = GdipDrawCurveI(graphics, pen, points, 1);
+    expect(InvalidParameter, status);
+
+    /* Valid test cases */
+    status = GdipDrawCurveI(graphics, pen, points, 2);
+    expect(Ok, status);
+
+    status = GdipDrawCurveI(graphics, pen, points, 3);
     expect(Ok, status);
 
     GdipDeletePen(pen);
     expect(Ok, status);
 
     GdipDeletePen(pen);
@@ -375,8 +962,6 @@ static void test_GdipDrawLineI(void)
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
-    status = GdipCreateFromHDC(hdc, &graphics);
-    expect(Ok, status);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
@@ -416,8 +1001,6 @@ static void test_GdipDrawLinesI(void)
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
     HDC hdc = GetDC(0);
 
     /* make a graphics object and pen object */
-    status = GdipCreateFromHDC(hdc, &graphics);
-    expect(Ok, status);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
     ok(hdc != NULL, "Expected HDC to be initialized\n");
 
     status = GdipCreateFromHDC(hdc, &graphics);
@@ -755,6 +1338,7 @@ static void test_Get_Release_DC(void)
     GdipDeletePen(pen);
     GdipDeleteGraphics(graphics);
 
     GdipDeletePen(pen);
     GdipDeleteGraphics(graphics);
 
+    GdipDeleteRegion(clip);
     GdipDeletePath(path);
     GdipDeleteBrush((GpBrush*)brush);
     GdipDeleteRegion(region);
     GdipDeletePath(path);
     GdipDeleteBrush((GpBrush*)brush);
     GdipDeleteRegion(region);
@@ -1077,6 +1661,614 @@ static void test_GdipDrawString(void)
     ReleaseDC(0, hdc);
 }
 
     ReleaseDC(0, hdc);
 }
 
+static void test_GdipGetVisibleClipBounds_screen(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    HDC hdc = GetDC(0);
+    GpRectF rectf, exp, clipr;
+    GpRect recti;
+
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    /* no clipping rect */
+    exp.X = 0;
+    exp.Y = 0;
+    exp.Width = GetDeviceCaps(hdc, HORZRES);
+    exp.Height = GetDeviceCaps(hdc, VERTRES);
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == exp.X &&
+        rectf.Y == exp.Y &&
+        rectf.Width == exp.Width &&
+        rectf.Height == exp.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the screen (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    /* clipping rect entirely within window */
+    exp.X = clipr.X = 10;
+    exp.Y = clipr.Y = 12;
+    exp.Width = clipr.Width = 14;
+    exp.Height = clipr.Height = 16;
+
+    status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
+    expect(Ok, status);
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == exp.X &&
+        rectf.Y == exp.Y &&
+        rectf.Width == exp.Width &&
+        rectf.Height == exp.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    /* clipping rect partially outside of screen */
+    clipr.X = -10;
+    clipr.Y = -12;
+    clipr.Width = 20;
+    clipr.Height = 24;
+
+    status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
+    expect(Ok, status);
+
+    exp.X = 0;
+    exp.Y = 0;
+    exp.Width = 10;
+    exp.Height = 12;
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == exp.X &&
+        rectf.Y == exp.Y &&
+        rectf.Width == exp.Width &&
+        rectf.Height == exp.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    status = GdipGetVisibleClipBoundsI(graphics, &recti);
+    expect(Ok, status);
+    ok(recti.X == exp.X &&
+        recti.Y == exp.Y &&
+        recti.Width == exp.Width &&
+        recti.Height == exp.Height,
+        "Expected clip bounds (%d, %d, %d, %d) to be the size of "
+        "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        recti.X, recti.Y, recti.Width, recti.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    GdipDeleteGraphics(graphics);
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipGetVisibleClipBounds_window(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpRectF rectf, window, exp, clipr;
+    GpRect recti;
+    HWND hwnd;
+    WNDCLASSA class;
+    HDC hdc;
+    PAINTSTRUCT ps;
+    HINSTANCE hInstance = GetModuleHandle(NULL);
+    RECT wnd_rect;
+
+    window.X = 0;
+    window.Y = 0;
+    window.Width = 200;
+    window.Height = 300;
+
+    class.lpszClassName = "ClipBoundsTestClass";
+    class.style = CS_HREDRAW | CS_VREDRAW;
+    class.lpfnWndProc = DefWindowProcA;
+    class.hInstance = hInstance;
+    class.hIcon = LoadIcon(0, IDI_APPLICATION);
+    class.hCursor = LoadCursor(NULL, IDC_ARROW);
+    class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+    class.lpszMenuName = 0;
+    class.cbClsExtra = 0;
+    class.cbWndExtra = 0;
+    RegisterClass(&class);
+
+    hwnd = CreateWindow(class.lpszClassName, "ClipboundsTest",
+        WS_OVERLAPPEDWINDOW, window.X, window.Y, window.Width, window.Height,
+        NULL, NULL, hInstance, NULL);
+
+    ok(hwnd != NULL, "Expected window to be created\n");
+
+    /* get client area size */
+    ok(GetClientRect(hwnd, &wnd_rect), "GetClientRect should have succeeded\n");
+    window.X = wnd_rect.left;
+    window.Y = wnd_rect.top;
+    window.Width = wnd_rect.right - wnd_rect.left;
+    window.Height = wnd_rect.bottom - wnd_rect.top;
+
+    hdc = BeginPaint(hwnd, &ps);
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == window.X &&
+        rectf.Y == window.Y &&
+        rectf.Width == window.Width &&
+        rectf.Height == window.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the window (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        window.X, window.Y, window.Width, window.Height);
+
+    /* clipping rect entirely within window */
+    exp.X = clipr.X = 20;
+    exp.Y = clipr.Y = 8;
+    exp.Width = clipr.Width = 30;
+    exp.Height = clipr.Height = 20;
+
+    status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
+    expect(Ok, status);
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == exp.X &&
+        rectf.Y == exp.Y &&
+        rectf.Width == exp.Width &&
+        rectf.Height == exp.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    /* clipping rect partially outside of window */
+    clipr.X = window.Width - 10;
+    clipr.Y = window.Height - 15;
+    clipr.Width = 20;
+    clipr.Height = 30;
+
+    status = GdipSetClipRect(graphics, clipr.X, clipr.Y, clipr.Width, clipr.Height, CombineModeReplace);
+    expect(Ok, status);
+
+    exp.X = window.Width - 10;
+    exp.Y = window.Height - 15;
+    exp.Width = 10;
+    exp.Height = 15;
+
+    status = GdipGetVisibleClipBounds(graphics, &rectf);
+    expect(Ok, status);
+    ok(rectf.X == exp.X &&
+        rectf.Y == exp.Y &&
+        rectf.Width == exp.Width &&
+        rectf.Height == exp.Height,
+        "Expected clip bounds (%0.f, %0.f, %0.f, %0.f) to be the size of "
+        "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        rectf.X, rectf.Y, rectf.Width, rectf.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    status = GdipGetVisibleClipBoundsI(graphics, &recti);
+    expect(Ok, status);
+    ok(recti.X == exp.X &&
+        recti.Y == exp.Y &&
+        recti.Width == exp.Width &&
+        recti.Height == exp.Height,
+        "Expected clip bounds (%d, %d, %d, %d) to be the size of "
+        "the visible clipping rect (%0.f, %0.f, %0.f, %0.f)\n",
+        recti.X, recti.Y, recti.Width, recti.Height,
+        exp.X, exp.Y, exp.Width, exp.Height);
+
+    GdipDeleteGraphics(graphics);
+    EndPaint(hwnd, &ps);
+    DestroyWindow(hwnd);
+}
+
+static void test_GdipGetVisibleClipBounds(void)
+{
+    GpGraphics* graphics = NULL;
+    GpRectF rectf;
+    GpRect rect;
+    HDC hdc = GetDC(0);
+    GpStatus status;
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    /* test null parameters */
+    status = GdipGetVisibleClipBounds(graphics, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipGetVisibleClipBounds(NULL, &rectf);
+    expect(InvalidParameter, status);
+
+    status = GdipGetVisibleClipBoundsI(graphics, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipGetVisibleClipBoundsI(NULL, &rect);
+    expect(InvalidParameter, status);
+
+    GdipDeleteGraphics(graphics);
+    ReleaseDC(0, hdc);
+
+    test_GdipGetVisibleClipBounds_screen();
+    test_GdipGetVisibleClipBounds_window();
+}
+
+static void test_fromMemoryBitmap(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    GpBitmap *bitmap = NULL;
+    BYTE bits[48] = {0};
+
+    status = GdipCreateBitmapFromScan0(4, 4, 12, PixelFormat24bppRGB, bits, &bitmap);
+    expect(Ok, status);
+
+    status = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics);
+    expect(Ok, status);
+
+    status = GdipGraphicsClear(graphics, 0xff686868);
+    expect(Ok, status);
+
+    GdipDeleteGraphics(graphics);
+
+    /* drawing writes to the memory provided */
+    todo_wine expect(0x68, bits[10]);
+
+    GdipDisposeImage((GpImage*)bitmap);
+}
+
+static void test_GdipIsVisiblePoint(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    HDC hdc = GetDC(0);
+    REAL x, y;
+    BOOL val;
+
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    /* null parameters */
+    status = GdipIsVisiblePoint(NULL, 0, 0, &val);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisiblePoint(graphics, 0, 0, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisiblePointI(NULL, 0, 0, &val);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisiblePointI(graphics, 0, 0, NULL);
+    expect(InvalidParameter, status);
+
+    x = 0;
+    y = 0;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = -10;
+    y = 0;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 0;
+    y = -5;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 1;
+    y = 1;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
+
+    status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
+    expect(Ok, status);
+
+    x = 1;
+    y = 1;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 15.5;
+    y = 40.5;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    /* translate into the center of the rect */
+    GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
+
+    x = 0;
+    y = 0;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 25;
+    y = 40;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
+
+    /* corner cases */
+    x = 9;
+    y = 19;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 9.25;
+    y = 19.25;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 9.5;
+    y = 19.5;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 9.75;
+    y = 19.75;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 10;
+    y = 20;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 40;
+    y = 20;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 39;
+    y = 59;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 39.25;
+    y = 59.25;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 39.5;
+    y = 39.5;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 39.75;
+    y = 59.75;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 40;
+    y = 60;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 40.15;
+    y = 60.15;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    x = 10;
+    y = 60;
+    status = GdipIsVisiblePoint(graphics, x, y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    /* integer version */
+    x = 25;
+    y = 30;
+    status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "After clipping, expected (%.2f, %.2f) to be visible\n", x, y);
+
+    x = 50;
+    y = 100;
+    status = GdipIsVisiblePointI(graphics, (INT)x, (INT)y, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "After clipping, expected (%.2f, %.2f) not to be visible\n", x, y);
+
+    GdipDeleteGraphics(graphics);
+    ReleaseDC(0, hdc);
+}
+
+static void test_GdipIsVisibleRect(void)
+{
+    GpStatus status;
+    GpGraphics *graphics = NULL;
+    HDC hdc = GetDC(0);
+    REAL x, y, width, height;
+    BOOL val;
+
+    ok(hdc != NULL, "Expected HDC to be initialized\n");
+
+    status = GdipCreateFromHDC(hdc, &graphics);
+    expect(Ok, status);
+    ok(graphics != NULL, "Expected graphics to be initialized\n");
+
+    status = GdipIsVisibleRect(NULL, 0, 0, 0, 0, &val);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val);
+    expect(InvalidParameter, status);
+
+    status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL);
+    expect(InvalidParameter, status);
+
+    /* entirely within the visible region */
+    x = 0; width = 10;
+    y = 0; height = 10;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* partially outside */
+    x = -10; width = 20;
+    y = -10; height = 20;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* entirely outside */
+    x = -10; width = 5;
+    y = -10; height = 5;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace);
+    expect(Ok, status);
+
+    /* entirely within the visible region */
+    x = 12; width = 10;
+    y = 22; height = 10;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* partially outside */
+    x = 35; width = 10;
+    y = 55; height = 10;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* entirely outside */
+    x = 45; width = 5;
+    y = 65; height = 5;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    /* translate into center of clipping rect */
+    GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend);
+
+    x = 0; width = 10;
+    y = 0; height = 10;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    x = 25; width = 5;
+    y = 40; height = 5;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend);
+
+    /* corners entirely outside, but some intersections */
+    x = 0; width = 70;
+    y = 0; height = 90;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    x = 0; width = 70;
+    y = 0; height = 30;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    x = 0; width = 30;
+    y = 0; height = 90;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* edge cases */
+    x = 0; width = 10;
+    y = 20; height = 40;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    x = 10; width = 30;
+    y = 0; height = 20;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    x = 40; width = 10;
+    y = 20; height = 40;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    x = 10; width = 30;
+    y = 60; height = 10;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height);
+
+    /* rounding tests */
+    x = 0.4; width = 10.4;
+    y = 20; height = 40;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    x = 10; width = 30;
+    y = 0.4; height = 20.4;
+    status = GdipIsVisibleRect(graphics, x, y, width, height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    /* integer version */
+    x = 0; width = 30;
+    y = 0; height = 90;
+    status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    x = 12; width = 10;
+    y = 22; height = 10;
+    status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val);
+    expect(Ok, status);
+    ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height);
+
+    GdipDeleteGraphics(graphics);
+    ReleaseDC(0, hdc);
+}
 
 START_TEST(graphics)
 {
 
 START_TEST(graphics)
 {
@@ -1095,15 +2287,26 @@ START_TEST(graphics)
     test_GdipDrawBezierI();
     test_GdipDrawArc();
     test_GdipDrawArcI();
     test_GdipDrawBezierI();
     test_GdipDrawArc();
     test_GdipDrawArcI();
+    test_GdipDrawCurve();
+    test_GdipDrawCurveI();
+    test_GdipDrawCurve2();
+    test_GdipDrawCurve2I();
+    test_GdipDrawCurve3();
+    test_GdipDrawCurve3I();
     test_GdipDrawLineI();
     test_GdipDrawLinesI();
     test_GdipDrawString();
     test_GdipDrawLineI();
     test_GdipDrawLinesI();
     test_GdipDrawString();
+    test_GdipGetVisibleClipBounds();
+    test_GdipIsVisiblePoint();
+    test_GdipIsVisibleRect();
     test_Get_Release_DC();
     test_Get_Release_DC();
+    test_BeginContainer2();
     test_transformpoints();
     test_get_set_clip();
     test_isempty();
     test_clear();
     test_textcontrast();
     test_transformpoints();
     test_get_set_clip();
     test_isempty();
     test_clear();
     test_textcontrast();
+    test_fromMemoryBitmap();
 
     GdiplusShutdown(gdiplusToken);
 }
 
     GdiplusShutdown(gdiplusToken);
 }
index 6e257eb..5f4a92e 100644 (file)
@@ -410,11 +410,14 @@ static void test_worldbounds(void)
     status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL);
     expect(Ok, status);
     GdipDeletePath(path);
     status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL);
     expect(Ok, status);
     GdipDeletePath(path);
+    GdipDeleteMatrix(matrix);
 
     expectf(-209.6, bounds.X);
     expectf(-1274.8, bounds.Y);
     expectf(705.0, bounds.Width);
     expectf(945.0, bounds.Height);
 
     expectf(-209.6, bounds.X);
     expectf(-1274.8, bounds.Y);
     expectf(705.0, bounds.Width);
     expectf(945.0, bounds.Height);
+
+    GdipDeletePen(pen);
 }
 
 static path_test_t pathpath_path[] = {
 }
 
 static path_test_t pathpath_path[] = {
index 4443f88..522e5de 100644 (file)
 #include "gdiplus.h"
 #include "wine/test.h"
 
 #include "gdiplus.h"
 #include "wine/test.h"
 
-#define expect(expected, got) ok(((UINT)got) == ((UINT)expected), "Expected %.8x, got %.8x\n", (UINT)expected, (UINT)got)
+#define expect(expected, got) ok((UINT)(got) == (UINT)(expected), "Expected %.8x, got %.8x\n", (UINT)(expected), (UINT)(got))
 #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
 
 #define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
 
-static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
+static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
 {
 {
-    GUID raw;
     WCHAR bufferW[39];
     char buffer[39];
     char buffer2[39];
     WCHAR bufferW[39];
     char buffer[39];
     char buffer2[39];
-    GpStatus stat;
 
 
-    stat = GdipGetImageRawFormat(img, &raw);
-    ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
-    if(stat != Ok) return;
-    StringFromGUID2(&raw, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
+    StringFromGUID2(got, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
     StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
     if(todo)
     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer, sizeof(buffer), NULL, NULL);
     StringFromGUID2(expected, bufferW, sizeof(bufferW)/sizeof(bufferW[0]));
     WideCharToMultiByte(CP_ACP, 0, bufferW, sizeof(bufferW)/sizeof(bufferW[0]), buffer2, sizeof(buffer2), NULL, NULL);
     if(todo)
-        todo_wine ok_(__FILE__, line)(IsEqualGUID(&raw, expected), "Expected format %s, got %s\n", buffer2, buffer);
+        todo_wine ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
     else
     else
-        ok_(__FILE__, line)(IsEqualGUID(&raw, expected), "Expected format %s, got %s\n", buffer2, buffer);
+        ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
+}
+
+static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
+{
+    GUID raw;
+    GpStatus stat;
+
+    stat = GdipGetImageRawFormat(img, &raw);
+    ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
+    if(stat != Ok) return;
+    expect_guid(expected, &raw, line, todo);
 }
 
 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
 }
 
 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
@@ -177,6 +183,9 @@ static void test_GdipImageGetFrameDimensionsCount(void)
     GpStatus stat;
     const REAL WIDTH = 10.0, HEIGHT = 20.0;
     UINT w;
     GpStatus stat;
     const REAL WIDTH = 10.0, HEIGHT = 20.0;
     UINT w;
+    GUID dimension = {0};
+    UINT count;
+    ARGB color;
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
 
     bm = (GpBitmap*)0xdeadbeef;
     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm);
@@ -194,6 +203,26 @@ static void test_GdipImageGetFrameDimensionsCount(void)
     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
     expect(Ok, stat);
     expect(1, w);
     stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w);
     expect(Ok, stat);
     expect(1, w);
+
+    stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
+    expect(Ok, stat);
+    expect_guid(&FrameDimensionPage, &dimension, __LINE__, TRUE);
+
+    count = 12345;
+    stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
+    todo_wine expect(Ok, stat);
+    todo_wine expect(1, count);
+
+    GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
+
+    stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
+    expect(Ok, stat);
+
+    /* SelectActiveFrame has no effect on image data of memory bitmaps */
+    color = 0xdeadbeef;
+    GdipBitmapGetPixel(bm, 0, 0, &color);
+    expect(0xffffffff, color);
+
     GdipDisposeImage((GpImage*)bm);
 }
 
     GdipDisposeImage((GpImage*)bm);
 }
 
@@ -465,6 +494,7 @@ static void test_GdipCreateBitmapFromHBITMAP(void)
     const REAL HEIGHT2 = 20;
     HDC hdc;
     BITMAPINFO bmi;
     const REAL HEIGHT2 = 20;
     HDC hdc;
     BITMAPINFO bmi;
+    BYTE *bits;
 
     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
     expect(InvalidParameter, stat);
 
     stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL);
     expect(InvalidParameter, stat);
@@ -486,7 +516,7 @@ static void test_GdipCreateBitmapFromHBITMAP(void)
     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
     expect(Ok, stat);
     /* raw format */
     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
     expect(Ok, stat);
     /* raw format */
-    expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, TRUE);
+    expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
 
     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
     expectf(WIDTH2,  width);
 
     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
     expectf(WIDTH2,  width);
@@ -504,20 +534,31 @@ static void test_GdipCreateBitmapFromHBITMAP(void)
     bmi.bmiHeader.biPlanes = 1;
     bmi.bmiHeader.biCompression = BI_RGB;
 
     bmi.bmiHeader.biPlanes = 1;
     bmi.bmiHeader.biCompression = BI_RGB;
 
-    hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
+    hbm = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
     ok(hbm != NULL, "CreateDIBSection failed\n");
 
     ok(hbm != NULL, "CreateDIBSection failed\n");
 
+    bits[0] = 0;
+
     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
     expect(Ok, stat);
     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
     expectf(WIDTH1,  width);
     expectf(HEIGHT1, height);
     if (stat == Ok)
     stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm);
     expect(Ok, stat);
     expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height));
     expectf(WIDTH1,  width);
     expectf(HEIGHT1, height);
     if (stat == Ok)
+    {
+        /* test whether writing to the bitmap affects the original */
+        stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
+        expect(Ok, stat);
+
+        expect(0, bits[0]);
+
         GdipDisposeImage((GpImage*)gpbm);
         GdipDisposeImage((GpImage*)gpbm);
+    }
 
     LogPal = GdipAlloc(sizeof(LOGPALETTE));
     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
     LogPal->palVersion = 0x300;
 
     LogPal = GdipAlloc(sizeof(LOGPALETTE));
     ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
     LogPal->palVersion = 0x300;
+    LogPal->palNumEntries = 1;
     hpal = CreatePalette(LogPal);
     ok(hpal != NULL, "CreatePalette failed\n");
     GdipFree(LogPal);
     hpal = CreatePalette(LogPal);
     ok(hpal != NULL, "CreatePalette failed\n");
     GdipFree(LogPal);
@@ -564,12 +605,12 @@ static void test_GdipCloneImage(void)
     /* Create an image, clone it, delete the original, make sure the copy works */
     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
     expect(Ok, stat);
     /* Create an image, clone it, delete the original, make sure the copy works */
     stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm);
     expect(Ok, stat);
-    expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, TRUE);
+    expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
 
     image_src = ((GpImage*)bm);
     stat = GdipCloneImage(image_src, &image_dest);
     expect(Ok, stat);
 
     image_src = ((GpImage*)bm);
     stat = GdipCloneImage(image_src, &image_dest);
     expect(Ok, stat);
-    expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, TRUE);
+    expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
 
     stat = GdipDisposeImage((GpImage*)bm);
     expect(Ok, stat);
 
     stat = GdipDisposeImage((GpImage*)bm);
     expect(Ok, stat);
@@ -646,7 +687,7 @@ static void test_fromhicon(void)
        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
        expect(PixelFormat32bppARGB, format);
        /* raw format */
        stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
        expect(PixelFormat32bppARGB, format);
        /* raw format */
-       expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, TRUE);
+       expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
        GdipDisposeImage((GpImage*)bitmap);
     }
     DestroyIcon(hIcon);
        GdipDisposeImage((GpImage*)bitmap);
     }
     DestroyIcon(hIcon);
@@ -682,7 +723,7 @@ static void test_fromhicon(void)
         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
         expect(PixelFormat32bppARGB, format);
         /* raw format */
         stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format);
         expect(PixelFormat32bppARGB, format);
         /* raw format */
-        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, TRUE);
+        expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
         GdipDisposeImage((GpImage*)bitmap);
     }
     DestroyIcon(hIcon);
         GdipDisposeImage((GpImage*)bitmap);
     }
     DestroyIcon(hIcon);
@@ -735,10 +776,320 @@ static const unsigned char jpgimage[285] = {
 };
 static void test_getrawformat(void)
 {
 };
 static void test_getrawformat(void)
 {
-    test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, TRUE);
-    test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, TRUE);
+    test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG,  __LINE__, FALSE);
+    test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF,  __LINE__, FALSE);
     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
     test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP,  __LINE__, FALSE);
-    test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, TRUE);
+    test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
+}
+
+static void test_createhbitmap(void)
+{
+    GpStatus stat;
+    GpBitmap *bitmap;
+    HBITMAP hbitmap, oldhbitmap;
+    BITMAP bm;
+    int ret;
+    HDC hdc;
+    COLORREF pixel;
+    BYTE bits[640];
+
+    memset(bits, 0x68, 640);
+
+    /* create Bitmap */
+    stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap);
+    expect(Ok, stat);
+
+    /* test NULL values */
+    stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0);
+    expect(InvalidParameter, stat);
+
+    stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0);
+    expect(InvalidParameter, stat);
+
+    /* create HBITMAP */
+    stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0);
+    expect(Ok, stat);
+
+    if (stat == Ok)
+    {
+        ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
+        expect(sizeof(BITMAP), ret);
+
+        expect(0, bm.bmType);
+        expect(10, bm.bmWidth);
+        expect(20, bm.bmHeight);
+        expect(40, bm.bmWidthBytes);
+        expect(1, bm.bmPlanes);
+        expect(32, bm.bmBitsPixel);
+        ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
+
+        hdc = CreateCompatibleDC(NULL);
+
+        oldhbitmap = SelectObject(hdc, hbitmap);
+        pixel = GetPixel(hdc, 5, 5);
+        SelectObject(hdc, oldhbitmap);
+
+        DeleteDC(hdc);
+
+        expect(0x686868, pixel);
+
+        DeleteObject(hbitmap);
+    }
+
+    stat = GdipDisposeImage((GpImage*)bitmap);
+    expect(Ok, stat);
+}
+
+static void test_getsetpixel(void)
+{
+    GpStatus stat;
+    GpBitmap *bitmap;
+    ARGB color;
+    BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
+                     0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
+
+    stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap);
+    expect(Ok, stat);
+
+    /* null parameters */
+    stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
+    expect(InvalidParameter, stat);
+
+    /* out of bounds */
+    stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
+    ok(stat == InvalidParameter ||
+       broken(stat == Ok), /* Older gdiplus */
+       "Expected InvalidParameter, got %.8x\n", stat);
+
+    stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
+    ok(stat == InvalidParameter ||
+       broken(stat == Ok), /* Older gdiplus */
+       "Expected InvalidParameter, got %.8x\n", stat);
+
+    stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
+    expect(InvalidParameter, stat);
+
+    stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
+    expect(InvalidParameter, stat);
+
+    /* valid use */
+    stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
+    expect(Ok, stat);
+    expect(0xffffffff, color);
+
+    stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
+    expect(Ok, stat);
+    expect(0xff0000ff, color);
+
+    stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
+    expect(Ok, stat);
+
+    stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
+    expect(Ok, stat);
+
+    stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
+    expect(Ok, stat);
+    expect(0xff676869, color);
+
+    stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
+    expect(Ok, stat);
+    expect(0xff474849, color);
+
+    stat = GdipDisposeImage((GpImage*)bitmap);
+    expect(Ok, stat);
+}
+
+static void check_halftone_palette(ColorPalette *palette)
+{
+    static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
+    UINT i;
+
+    for (i=0; i<palette->Count; i++)
+    {
+        ARGB expected=0xff000000;
+        if (i<8)
+        {
+            if (i&1) expected |= 0x800000;
+            if (i&2) expected |= 0x8000;
+            if (i&4) expected |= 0x80;
+        }
+        else if (i == 8)
+        {
+            expected = 0xffc0c0c0;
+        }
+        else if (i < 16)
+        {
+            if (i&1) expected |= 0xff0000;
+            if (i&2) expected |= 0xff00;
+            if (i&4) expected |= 0xff;
+        }
+        else if (i < 40)
+        {
+            expected = 0x00000000;
+        }
+        else
+        {
+            expected |= halftone_values[(i-40)%6];
+            expected |= halftone_values[((i-40)/6)%6] << 8;
+            expected |= halftone_values[((i-40)/36)%6] << 16;
+        }
+        ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
+            expected, palette->Entries[i], i, palette->Count);
+    }
+}
+
+static void test_palette(void)
+{
+    GpStatus stat;
+    GpBitmap *bitmap;
+    INT size;
+    BYTE buffer[1040];
+    ColorPalette *palette=(ColorPalette*)buffer;
+
+    /* test initial palette from non-indexed bitmap */
+    stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap);
+    expect(Ok, stat);
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB), size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(0, palette->Count);
+
+    /* test setting palette on not-indexed bitmap */
+    palette->Count = 3;
+
+    stat = GdipSetImagePalette((GpImage*)bitmap, palette);
+    expect(Ok, stat);
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(3, palette->Count);
+
+    GdipDisposeImage((GpImage*)bitmap);
+
+    /* test initial palette on 1-bit bitmap */
+    stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap);
+    expect(Ok, stat);
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(PaletteFlagsGrayScale, palette->Flags);
+    expect(2, palette->Count);
+
+    expect(0xff000000, palette->Entries[0]);
+    expect(0xffffffff, palette->Entries[1]);
+
+    GdipDisposeImage((GpImage*)bitmap);
+
+    /* test initial palette on 4-bit bitmap */
+    stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap);
+    expect(Ok, stat);
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(0, palette->Flags);
+    expect(16, palette->Count);
+
+    check_halftone_palette(palette);
+
+    GdipDisposeImage((GpImage*)bitmap);
+
+    /* test initial palette on 8-bit bitmap */
+    stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap);
+    expect(Ok, stat);
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(PaletteFlagsHalftone, palette->Flags);
+    expect(256, palette->Count);
+
+    check_halftone_palette(palette);
+
+    /* test setting/getting a different palette */
+    palette->Entries[1] = 0xffcccccc;
+
+    stat = GdipSetImagePalette((GpImage*)bitmap, palette);
+    expect(Ok, stat);
+
+    palette->Entries[1] = 0;
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(PaletteFlagsHalftone, palette->Flags);
+    expect(256, palette->Count);
+    expect(0xffcccccc, palette->Entries[1]);
+
+    /* test count < 256 */
+    palette->Flags = 12345;
+    palette->Count = 3;
+
+    stat = GdipSetImagePalette((GpImage*)bitmap, palette);
+    expect(Ok, stat);
+
+    palette->Entries[1] = 0;
+    palette->Entries[3] = 0xdeadbeef;
+
+    stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size);
+    expect(Ok, stat);
+    expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
+
+    stat = GdipGetImagePalette((GpImage*)bitmap, palette, size);
+    expect(Ok, stat);
+    expect(12345, palette->Flags);
+    expect(3, palette->Count);
+    expect(0xffcccccc, palette->Entries[1]);
+    expect(0xdeadbeef, palette->Entries[3]);
+
+    /* test count > 256 */
+    palette->Count = 257;
+
+    stat = GdipSetImagePalette((GpImage*)bitmap, palette);
+    ok(stat == InvalidParameter ||
+       broken(stat == Ok), /* Old gdiplus behavior */
+       "Expected %.8x, got %.8x\n", InvalidParameter, stat);
+
+    GdipDisposeImage((GpImage*)bitmap);
 }
 
 START_TEST(image)
 }
 
 START_TEST(image)
@@ -766,6 +1117,9 @@ START_TEST(image)
     test_testcontrol();
     test_fromhicon();
     test_getrawformat();
     test_testcontrol();
     test_fromhicon();
     test_getrawformat();
+    test_createhbitmap();
+    test_getsetpixel();
+    test_palette();
 
     GdiplusShutdown(gdiplusToken);
 }
 
     GdiplusShutdown(gdiplusToken);
 }
index eddb24e..3e1c287 100644 (file)
@@ -36,8 +36,11 @@ static void test_constructor_destructor(void)
     /* NULL args */
     stat = GdipCreatePathIter(NULL, NULL);
     expect(InvalidParameter, stat);
     /* NULL args */
     stat = GdipCreatePathIter(NULL, NULL);
     expect(InvalidParameter, stat);
+    iter = NULL;
     stat = GdipCreatePathIter(&iter, NULL);
     expect(Ok, stat);
     stat = GdipCreatePathIter(&iter, NULL);
     expect(Ok, stat);
+    ok(iter != NULL, "Expected iterator to be created\n");
+    GdipDeletePathIter(iter);
     stat = GdipCreatePathIter(NULL, path);
     expect(InvalidParameter, stat);
     stat = GdipDeletePathIter(NULL);
     stat = GdipCreatePathIter(NULL, path);
     expect(InvalidParameter, stat);
     stat = GdipDeletePathIter(NULL);
index d2f33f0..0bdf280 100644 (file)
@@ -33,21 +33,28 @@ static void test_startup(void)
     Status status;
     struct GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;
     Status status;
     struct GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;
+    int gpversion;
 
 
-    gdiplusStartupInput.GdiplusVersion              = 1;
     gdiplusStartupInput.DebugEventCallback          = NULL;
     gdiplusStartupInput.SuppressBackgroundThread    = 0;
     gdiplusStartupInput.SuppressExternalCodecs      = 0;
 
     gdiplusStartupInput.DebugEventCallback          = NULL;
     gdiplusStartupInput.SuppressBackgroundThread    = 0;
     gdiplusStartupInput.SuppressExternalCodecs      = 0;
 
-    status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
-    expect(Ok, status);
-    GdiplusShutdown(gdiplusToken);
-
-    gdiplusStartupInput.GdiplusVersion = 2;
-
-    status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
-    expect(UnsupportedGdiplusVersion, status);
-    GdiplusShutdown(gdiplusToken);
+    for (gpversion=1; gpversion<256; gpversion++)
+    {
+        gdiplusStartupInput.GdiplusVersion = gpversion;
+        status = GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
+        ok(status == Ok || status == UnsupportedGdiplusVersion,
+            "GdiplusStartup returned %x\n", status);
+        GdiplusShutdown(gdiplusToken);
+        if (status != Ok)
+        {
+            gpversion--;
+            break;
+        }
+    }
+
+    ok(gpversion > 0 && gpversion <= 2, "unexpected gdiplus version %i\n", gpversion);
+    trace("gdiplus version is %i\n", gpversion);
 
     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
 
 
     status = GdipCreatePen1((ARGB)0xffff00ff, 10.0f, UnitPixel, &pen);
 
@@ -219,7 +226,8 @@ static void test_dasharray(void)
     /* Try to set with count = 0. */
     GdipSetPenDashStyle(pen, DashStyleDot);
     status = GdipSetPenDashArray(pen, dashes, 0);
     /* Try to set with count = 0. */
     GdipSetPenDashStyle(pen, DashStyleDot);
     status = GdipSetPenDashArray(pen, dashes, 0);
-    expect(OutOfMemory, status);
+    ok(status == OutOfMemory || status == InvalidParameter,
+       "Expected OutOfMemory or InvalidParameter, got %.8x\n", status);
     GdipGetPenDashStyle(pen, &style);
     expect(DashStyleDot, style);
 
     GdipGetPenDashStyle(pen, &style);
     expect(DashStyleDot, style);