diff --git a/Tests/Perspex.RenderTests/Media/ImageBrushTests.cs b/Tests/Perspex.RenderTests/Media/ImageBrushTests.cs
index 21a3047529..2c958977b7 100644
--- a/Tests/Perspex.RenderTests/Media/ImageBrushTests.cs
+++ b/Tests/Perspex.RenderTests/Media/ImageBrushTests.cs
@@ -26,11 +26,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
get { return System.IO.Path.Combine(OutputPath, "github_icon.png"); }
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_Alignment_TopLeft()
{
Decorator target = new Decorator
@@ -55,11 +51,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_Alignment_Center()
{
Decorator target = new Decorator
@@ -84,11 +76,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_Alignment_BottomRight()
{
Decorator target = new Decorator
@@ -113,11 +101,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_Fill_NoTile()
{
Decorator target = new Decorator
@@ -140,11 +124,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_Uniform_NoTile()
{
Decorator target = new Decorator
@@ -167,11 +147,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_UniformToFill_NoTile()
{
Decorator target = new Decorator
@@ -194,11 +170,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_BottomRightQuarterSource()
{
Decorator target = new Decorator
@@ -222,11 +194,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_BottomRightQuarterDest()
{
Decorator target = new Decorator
@@ -250,11 +218,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest()
{
Decorator target = new Decorator
@@ -279,11 +243,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest()
{
Decorator target = new Decorator
@@ -309,7 +269,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
}
#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
+ [Fact(Skip = "TileMode.FlipX not yet supported on cairo")]
#else
[Fact]
#endif
@@ -337,7 +297,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
}
#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
+ [Fact(Skip = "TileMode.FlipY not yet supported on cairo")]
#else
[Fact]
#endif
@@ -364,11 +324,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "ImageBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void ImageBrush_NoStretch_FlipXY_TopLeftDest()
{
Decorator target = new Decorator
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Fill_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Fill_NoTile.expected.png
new file mode 100644
index 0000000000..73d147bf77
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Fill_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipXY_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipXY_TopLeftDest.expected.png
new file mode 100644
index 0000000000..f99f56ec14
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipXY_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipX_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipX_TopLeftDest.expected.png
new file mode 100644
index 0000000000..4d89f995c4
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipX_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipY_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipY_TopLeftDest.expected.png
new file mode 100644
index 0000000000..75c53f0c28
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_FlipY_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png
new file mode 100644
index 0000000000..a13b34ba2d
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_Center.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_Center.expected.png
new file mode 100644
index 0000000000..14704f751c
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_Center.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png
new file mode 100644
index 0000000000..7ebac13d30
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png
new file mode 100644
index 0000000000..dd41cb98c3
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png
new file mode 100644
index 0000000000..ab9f2b76e3
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png
new file mode 100644
index 0000000000..fea4a2a8e9
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png
new file mode 100644
index 0000000000..afd39c2360
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_UniformToFill_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_UniformToFill_NoTile.expected.png
new file mode 100644
index 0000000000..e173fa6cee
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_UniformToFill_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Uniform_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Uniform_NoTile.expected.png
new file mode 100644
index 0000000000..de73af8170
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/ImageBrush_Uniform_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/ImageBrush/github_icon.png b/Tests/TestFiles/Cairo/Media/ImageBrush/github_icon.png
new file mode 100644
index 0000000000..cd053c5fe1
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/ImageBrush/github_icon.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png
deleted file mode 100644
index 0918b7fd51..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png
deleted file mode 100644
index dc6050fec4..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png
deleted file mode 100644
index 905ec5386a..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png
deleted file mode 100644
index 9253eee164..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Fill_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Fill_NoTile.expected.png
new file mode 100644
index 0000000000..842e541de9
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Fill_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png
deleted file mode 100644
index da7003b419..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png
deleted file mode 100644
index 4bfcdb2dd3..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png
deleted file mode 100644
index 74a01bb78c..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipXY_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipXY_TopLeftDest.expected.png
new file mode 100644
index 0000000000..c719a0328b
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipXY_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipX_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipX_TopLeftDest.expected.png
new file mode 100644
index 0000000000..c64b88dc68
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipX_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipY_TopLeftDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipY_TopLeftDest.expected.png
new file mode 100644
index 0000000000..a6e8b0688c
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_FlipY_TopLeftDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png
new file mode 100644
index 0000000000..a13b34ba2d
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_BottomRight.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_Center.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_Center.expected.png
new file mode 100644
index 0000000000..9150e62edf
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_Center.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png
new file mode 100644
index 0000000000..7ebac13d30
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_Alignment_TopLeft.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png
new file mode 100644
index 0000000000..c8ac46f84c
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png
new file mode 100644
index 0000000000..ab9f2b76e3
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png
new file mode 100644
index 0000000000..fea4a2a8e9
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png
new file mode 100644
index 0000000000..afd39c2360
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png
deleted file mode 100644
index e1fcdbc1a6..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png
deleted file mode 100644
index b2abed4041..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png
deleted file mode 100644
index 1aedd35831..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png
deleted file mode 100644
index f1914a404f..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png
deleted file mode 100644
index fb2ae9f8cc..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png
deleted file mode 100644
index d0009b6abb..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png
deleted file mode 100644
index 64695d4bb1..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png
deleted file mode 100644
index 0918b7fd51..0000000000
Binary files a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png and /dev/null differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_UniformToFill_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_UniformToFill_NoTile.expected.png
new file mode 100644
index 0000000000..f56ff5f5f6
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_UniformToFill_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Uniform_NoTile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Uniform_NoTile.expected.png
new file mode 100644
index 0000000000..d0a982fcd5
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Uniform_NoTile.expected.png differ
diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/github_icon.png b/Tests/TestFiles/Cairo/Media/VisualBrush/github_icon.png
new file mode 100644
index 0000000000..cd053c5fe1
Binary files /dev/null and b/Tests/TestFiles/Cairo/Media/VisualBrush/github_icon.png differ
diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
index 895fbaa26e..0bf21e31af 100644
--- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
+++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
@@ -216,6 +216,8 @@ namespace Perspex.Cairo.Media
{
var solid = brush as SolidColorBrush;
var linearGradientBrush = brush as LinearGradientBrush;
+ var imageBrush = brush as ImageBrush;
+ var visualBrush = brush as VisualBrush;
if (solid != null)
{
@@ -236,9 +238,17 @@ namespace Perspex.Cairo.Media
g.AddColorStop(s.Offset, s.Color.ToCairo());
g.Extend = Cairo.Extend.Pad;
-
+
_context.SetSource(g);
}
+ else if (imageBrush != null)
+ {
+ _context.SetSource(TileBrushes.CreateImageBrush(imageBrush, destinationSize));
+ }
+ else if (visualBrush != null)
+ {
+ _context.SetSource(TileBrushes.CreateVisualBrush(visualBrush, destinationSize));
+ }
}
private void SetPen(Pen pen, Size destinationSize)
diff --git a/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs
new file mode 100644
index 0000000000..016954030f
--- /dev/null
+++ b/src/Gtk/Perspex.Cairo/Media/TileBrushes.cs
@@ -0,0 +1,224 @@
+// Copyright (c) The Perspex Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Cairo;
+using Perspex.Cairo.Media.Imaging;
+using Perspex.Layout;
+using Perspex.Media;
+using Perspex.Platform;
+
+namespace Perspex.Cairo.Media
+{
+ internal static class TileBrushes
+ {
+ public static SurfacePattern CreateImageBrush(ImageBrush brush, Size targetSize)
+ {
+ if (brush.Source == null)
+ {
+ return null;
+ }
+
+ // TODO: This is directly ported from Direct2D and could probably be made more
+ // efficient on cairo by taking advantage of the fact that cairo has Extend.None.
+ var image = ((BitmapImpl)brush.Source.PlatformImpl).Surface;
+ var imageSize = new Size(brush.Source.PixelWidth, brush.Source.PixelHeight);
+ var tileMode = brush.TileMode;
+ var sourceRect = brush.SourceRect.ToPixels(imageSize);
+ var destinationRect = brush.DestinationRect.ToPixels(targetSize);
+ var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
+ var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
+ var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size);
+ var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height);
+
+ using (var context = new Context(intermediate))
+ {
+ Rect drawRect;
+ var transform = CalculateIntermediateTransform(
+ tileMode,
+ sourceRect,
+ destinationRect,
+ scale,
+ translate,
+ out drawRect);
+ context.Rectangle(drawRect.ToCairo());
+ context.Clip();
+ context.Transform(transform.ToCairo());
+ Gdk.CairoHelper.SetSourcePixbuf(context, image, 0, 0);
+ context.Rectangle(0, 0, imageSize.Width, imageSize.Height);
+ context.Fill();
+
+ var result = new SurfacePattern(intermediate);
+
+ if ((brush.TileMode & TileMode.FlipXY) != 0)
+ {
+ // TODO: Currently always FlipXY as that's all cairo supports natively.
+ // Support separate FlipX and FlipY by drawing flipped images to intermediate
+ // surface.
+ result.Extend = Extend.Reflect;
+ }
+ else
+ {
+ result.Extend = Extend.Repeat;
+ }
+
+ if (brush.TileMode != TileMode.None)
+ {
+ var matrix = result.Matrix;
+ matrix.InitTranslate(-destinationRect.X, -destinationRect.Y);
+ result.Matrix = matrix;
+ }
+
+ return result;
+ }
+ }
+
+ public static SurfacePattern CreateVisualBrush(VisualBrush brush, Size targetSize)
+ {
+ var visual = brush.Visual;
+
+ if (visual == null)
+ {
+ return null;
+ }
+
+ var layoutable = visual as ILayoutable;
+
+ if (layoutable?.IsArrangeValid == false)
+ {
+ layoutable.Measure(Size.Infinity);
+ layoutable.Arrange(new Rect(layoutable.DesiredSize));
+ }
+
+ // TODO: This is directly ported from Direct2D and could probably be made more
+ // efficient on cairo by taking advantage of the fact that cairo has Extend.None.
+ var tileMode = brush.TileMode;
+ var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
+ var destinationRect = brush.DestinationRect.ToPixels(targetSize);
+ var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
+ var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
+ var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size);
+ var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height);
+
+ using (var context = new Context(intermediate))
+ {
+ Rect drawRect;
+ var transform = CalculateIntermediateTransform(
+ tileMode,
+ sourceRect,
+ destinationRect,
+ scale,
+ translate,
+ out drawRect);
+ var renderer = new Renderer(intermediate);
+
+ context.Rectangle(drawRect.ToCairo());
+ context.Clip();
+ context.Transform(transform.ToCairo());
+ renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect);
+
+ var result = new SurfacePattern(intermediate);
+
+ if ((brush.TileMode & TileMode.FlipXY) != 0)
+ {
+ // TODO: Currently always FlipXY as that's all cairo supports natively.
+ // Support separate FlipX and FlipY by drawing flipped images to intermediate
+ // surface.
+ result.Extend = Extend.Reflect;
+ }
+ else
+ {
+ result.Extend = Extend.Repeat;
+ }
+
+ if (brush.TileMode != TileMode.None)
+ {
+ var matrix = result.Matrix;
+ matrix.InitTranslate(-destinationRect.X, -destinationRect.Y);
+ result.Matrix = matrix;
+ }
+
+ return result;
+ }
+ }
+
+ ///
+ /// Calculates a translate based on a , a source and destination
+ /// rectangle and a scale.
+ ///
+ /// The brush.
+ /// The source rectangle.
+ /// The destination rectangle.
+ /// The scale factor.
+ /// A vector with the X and Y translate.
+ private static Vector CalculateTranslate(
+ TileBrush brush,
+ Rect sourceRect,
+ Rect destinationRect,
+ Vector scale)
+ {
+ var x = 0.0;
+ var y = 0.0;
+ var size = sourceRect.Size * scale;
+
+ switch (brush.AlignmentX)
+ {
+ case AlignmentX.Center:
+ x += (destinationRect.Width - size.Width) / 2;
+ break;
+ case AlignmentX.Right:
+ x += destinationRect.Width - size.Width;
+ break;
+ }
+
+ switch (brush.AlignmentY)
+ {
+ case AlignmentY.Center:
+ y += (destinationRect.Height - size.Height) / 2;
+ break;
+ case AlignmentY.Bottom:
+ y += destinationRect.Height - size.Height;
+ break;
+ }
+
+ return new Vector(x, y);
+ }
+
+ private static Size CalculateIntermediateSize(
+ TileMode tileMode,
+ Size targetSize,
+ Size destinationSize)
+ {
+ var result = tileMode == TileMode.None ? targetSize : destinationSize;
+ return result;
+ }
+
+ private static Matrix CalculateIntermediateTransform(
+ TileMode tileMode,
+ Rect sourceRect,
+ Rect destinationRect,
+ Vector scale,
+ Vector translate,
+ out Rect drawRect)
+ {
+ var transform = Matrix.CreateTranslation(-sourceRect.Position) *
+ Matrix.CreateScale(scale) *
+ Matrix.CreateTranslation(translate);
+ Rect dr;
+
+ if (tileMode == TileMode.None)
+ {
+ dr = destinationRect;
+ transform *= Matrix.CreateTranslation(destinationRect.Position);
+ }
+ else
+ {
+ dr = new Rect(destinationRect.Size);
+ }
+
+ drawRect = dr;
+
+ return transform;
+ }
+ }
+}
diff --git a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj
index 3232d64281..1461d6006b 100644
--- a/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj
+++ b/src/Gtk/Perspex.Cairo/Perspex.Cairo.csproj
@@ -72,6 +72,7 @@
+
@@ -87,6 +88,10 @@
{B09B78D8-9B26-48B0-9149-D64A2F120F3F}
Perspex.Base
+
+ {42472427-4774-4c81-8aff-9f27b8e31721}
+ Perspex.Layout
+
{EB582467-6ABB-43A1-B052-E981BA910E3A}
Perspex.SceneGraph
diff --git a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs
index 7003adca0b..e4c23894d9 100644
--- a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs
+++ b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs
@@ -58,11 +58,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
}
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_Alignment_TopLeft()
{
Decorator target = new Decorator
@@ -87,11 +83,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_Alignment_Center()
{
Decorator target = new Decorator
@@ -116,11 +108,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_Alignment_BottomRight()
{
Decorator target = new Decorator
@@ -145,11 +133,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_Fill_NoTile()
{
Decorator target = new Decorator
@@ -172,11 +156,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_Uniform_NoTile()
{
Decorator target = new Decorator
@@ -199,11 +179,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_UniformToFill_NoTile()
{
Decorator target = new Decorator
@@ -226,11 +202,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_BottomRightQuarterSource()
{
Decorator target = new Decorator
@@ -254,11 +226,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_BottomRightQuarterDest()
{
Decorator target = new Decorator
@@ -282,11 +250,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_NoTile_BottomRightQuarterSource_BottomRightQuarterDest()
{
Decorator target = new Decorator
@@ -311,11 +275,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_Tile_BottomRightQuarterSource_CenterQuarterDest()
{
Decorator target = new Decorator
@@ -341,7 +301,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
}
#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
+ [Fact(Skip = "TileMode.FlipX not yet supported on cairo")]
#else
[Fact]
#endif
@@ -369,7 +329,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
}
#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
+ [Fact(Skip = "TileMode.FlipY not yet supported on cairo")]
#else
[Fact]
#endif
@@ -396,11 +356,7 @@ namespace Perspex.Direct2D1.RenderTests.Media
CompareImages();
}
-#if PERSPEX_CAIRO
- [Fact(Skip = "VisualBrush not yet implemented on Cairo")]
-#else
[Fact]
-#endif
public void VisualBrush_NoStretch_FlipXY_TopLeftDest()
{
Decorator target = new Decorator
diff --git a/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj b/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj
index 024b77b93d..01a3546f39 100644
--- a/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj
+++ b/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj
@@ -74,6 +74,7 @@
+