[gdiplus_winetest]
[reactos.git] / rostests / winetests / gdiplus / graphics.c
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);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     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);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     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);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_c);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipRestoreGraphics(graphics1, state_a);
     GdipGetInterpolationMode(graphics1, &mode);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     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);
-    todo_wine
-        expect(InterpolationModeBilinear, mode);
+    expect(InterpolationModeBilinear, mode);
     GdipRestoreGraphics(graphics2, state_b);
     GdipGetInterpolationMode(graphics2, &mode);
-    todo_wine
-        expect(InterpolationModeBicubic, mode);
+    expect(InterpolationModeBicubic, mode);
     GdipDeleteGraphics(graphics1);
     GdipDeleteGraphics(graphics2);
 
@@ -243,8 +235,6 @@ static void test_GdipDrawArc(void)
     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);
@@ -289,8 +279,577 @@ static void test_GdipDrawArcI(void)
     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);
+    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);
@@ -301,24 +860,31 @@ static void test_GdipDrawArcI(void)
     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);
 
-    status = GdipDrawArcI(graphics, NULL, 0, 0, 1, 1, 0, 0);
+    status = GdipDrawCurve(graphics, NULL, points, 3);
     expect(InvalidParameter, status);
 
-    status = GdipDrawArcI(NULL, pen, 0, 0, 1, 1, 0, 0);
+    status = GdipDrawCurve(NULL, pen, points, 3);
     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);
 
-    status = GdipDrawArcI(graphics, pen, 0, 0, 0, 1, 0, 0);
+    status = GdipDrawCurve(graphics, pen, points, 0);
     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);
@@ -327,16 +893,24 @@ static void test_GdipDrawArcI(void)
     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);
+    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 */
-    status = GdipCreateFromHDC(hdc, &graphics);
-    expect(Ok, status);
     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 */
-    status = GdipDrawBezierI(NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(NULL, NULL, points, 3);
     expect(InvalidParameter, status);
 
-    status = GdipDrawBezierI(graphics, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(graphics, NULL, points, 3);
     expect(InvalidParameter, status);
 
-    status = GdipDrawBezierI(NULL, pen, 0, 0, 0, 0, 0, 0, 0, 0);
+    status = GdipDrawCurveI(NULL, pen, points, 3);
     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);
@@ -375,8 +962,6 @@ static void test_GdipDrawLineI(void)
     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);
@@ -416,8 +1001,6 @@ static void test_GdipDrawLinesI(void)
     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);
@@ -755,6 +1338,7 @@ static void test_Get_Release_DC(void)
     GdipDeletePen(pen);
     GdipDeleteGraphics(graphics);
 
+    GdipDeleteRegion(clip);
     GdipDeletePath(path);
     GdipDeleteBrush((GpBrush*)brush);
     GdipDeleteRegion(region);
@@ -1077,6 +1661,614 @@ static void test_GdipDrawString(void)
     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)
 {
@@ -1095,15 +2287,26 @@ START_TEST(graphics)
     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_GdipGetVisibleClipBounds();
+    test_GdipIsVisiblePoint();
+    test_GdipIsVisibleRect();
     test_Get_Release_DC();
+    test_BeginContainer2();
     test_transformpoints();
     test_get_set_clip();
     test_isempty();
     test_clear();
     test_textcontrast();
+    test_fromMemoryBitmap();
 
     GdiplusShutdown(gdiplusToken);
 }