From c3bc823bd0f5d1631cfb3f56214b6a549676fc44 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 14 Sep 2015 21:18:22 +0300 Subject: [PATCH 01/20] GTK: Use InvalidateRect instead of Draw --- src/Gtk/Perspex.Gtk/WindowImpl.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Gtk/Perspex.Gtk/WindowImpl.cs b/src/Gtk/Perspex.Gtk/WindowImpl.cs index 4247a3d853..2e5da0c42f 100644 --- a/src/Gtk/Perspex.Gtk/WindowImpl.cs +++ b/src/Gtk/Perspex.Gtk/WindowImpl.cs @@ -78,9 +78,8 @@ namespace Perspex.Gtk public void Invalidate(Rect rect) { -#pragma warning disable CS0612 // Type or member is obsolete - Draw(new Rectangle { X = (int)rect.X, Y = (int)rect.Y, Width = (int)rect.Width, Height = (int)rect.Height }); -#pragma warning restore CS0612 // Type or member is obsolete + base.GdkWindow.InvalidateRect (new Rectangle ((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height), true); + } public Point PointToScreen(Point point) From 1eb7a41a4ab65e9aae4f73274beb9fbe4494b2c6 Mon Sep 17 00:00:00 2001 From: Nelson Carrillo Date: Mon, 14 Sep 2015 14:43:21 -0400 Subject: [PATCH 02/20] Fixing LinearGradientBrush colors on Cairo --- src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index 4c99590cb6..6a29fd728f 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -215,7 +215,7 @@ namespace Perspex.Cairo.Media Cairo.LinearGradient g = new Cairo.LinearGradient(linearGradientBrush.StartPoint.X * destinationSize.Width, linearGradientBrush.StartPoint.Y * destinationSize.Height, linearGradientBrush.EndPoint.X * destinationSize.Width, linearGradientBrush.EndPoint.Y * destinationSize.Height); foreach (var s in linearGradientBrush.GradientStops) - g.AddColorStopRgb(s.Offset, new Cairo.Color(s.Color.R, s.Color.G, s.Color.B, s.Color.A)); + g.AddColorStop(s.Offset, new Cairo.Color(s.Color.R / 255.0, s.Color.G / 255.0, s.Color.B / 255.0, s.Color.A / 255.0)); g.Extend = Cairo.Extend.Pad; From 846df81b761be85dde0cebaa1426f6e9ea92e2f2 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 13 Sep 2015 20:08:48 +0200 Subject: [PATCH 03/20] Whitespace. --- src/Perspex.Controls/Image.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Perspex.Controls/Image.cs b/src/Perspex.Controls/Image.cs index d34948e2ee..0782b51f2a 100644 --- a/src/Perspex.Controls/Image.cs +++ b/src/Perspex.Controls/Image.cs @@ -23,7 +23,7 @@ namespace Perspex.Controls /// public static readonly PerspexProperty StretchProperty = PerspexProperty.Register(nameof(Stretch), Stretch.Uniform); - + /// /// Gets or sets the bitmap image that will be displayed. /// From bfdc4cd487c7aa11d028c68fbe19cde9a506ae39 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 14 Sep 2015 22:19:41 +0200 Subject: [PATCH 04/20] Assign Surface in RTB. --- .../Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs index 8c017d9cfd..ef816d6910 100644 --- a/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/Imaging/RenderTargetBitmapImpl.cs @@ -10,10 +10,9 @@ namespace Perspex.Cairo.Media.Imaging public class RenderTargetBitmapImpl : IRenderTargetBitmapImpl { - public RenderTargetBitmapImpl( - Cairo.ImageSurface surface) + public RenderTargetBitmapImpl(Cairo.ImageSurface surface) { - + Surface = surface; } public int PixelWidth => Surface.Width; @@ -25,7 +24,6 @@ namespace Perspex.Cairo.Media.Imaging Surface.Dispose(); } - public Cairo.ImageSurface Surface { get; From 0963f913f2a19b628ab2e978cba1fd41ff679ca2 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 14 Sep 2015 23:50:39 +0200 Subject: [PATCH 05/20] Fixed cairo image tests. --- src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 26 +++++++++++++++---- src/Perspex.SceneGraph/Rect.cs | 24 ++++++----------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index 6a29fd728f..f82cc3cdcd 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -42,6 +42,9 @@ namespace Perspex.Cairo.Media CurrentTransform = Matrix.Identity; } + /// + /// Gets the current transform of the drawing context. + /// public Matrix CurrentTransform { get; } @@ -54,17 +57,30 @@ namespace Perspex.Cairo.Media _context.Dispose(); } + /// + /// Draws a bitmap image. + /// + /// The bitmap image. + /// The opacity to draw with. + /// The rect in the image to draw. + /// The rect in the output to draw to. public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect) { var impl = bitmap.PlatformImpl as BitmapImpl; var size = new Size(impl.PixelWidth, impl.PixelHeight); - var scaleX = destRect.Size.Width / sourceRect.Size.Width; - var scaleY = destRect.Size.Height / sourceRect.Size.Height; + var scale = new Vector(destRect.Width / sourceRect.Width, destRect.Height / sourceRect.Height); _context.Save(); - _context.Scale(scaleX, scaleY); - Gdk.CairoHelper.SetSourcePixbuf(_context, impl.Surface, (int)sourceRect.X, (int)sourceRect.Y); - _context.Rectangle(sourceRect.ToCairo()); + _context.Scale(scale.X, scale.Y); + destRect /= scale; + + Gdk.CairoHelper.SetSourcePixbuf( + _context, + impl.Surface, + -sourceRect.X + destRect.X, + -sourceRect.Y + destRect.Y); + + _context.Rectangle(destRect.ToCairo()); _context.Fill(); _context.Restore(); } diff --git a/src/Perspex.SceneGraph/Rect.cs b/src/Perspex.SceneGraph/Rect.cs index 95b08eedd6..2dba97e764 100644 --- a/src/Perspex.SceneGraph/Rect.cs +++ b/src/Perspex.SceneGraph/Rect.cs @@ -184,15 +184,11 @@ namespace Perspex /// The scaled rectangle. public static Rect operator *(Rect rect, Vector scale) { - double centerX = rect._x + (rect._width / 2); - double centerY = rect._y + (rect._height / 2); - double width = rect._width * scale.X; - double height = rect._height * scale.Y; return new Rect( - centerX - (width / 2), - centerY - (height / 2), - width, - height); + rect.X * scale.X, + rect.Y * scale.Y, + rect.Width * scale.X, + rect.Height * scale.Y); } /// @@ -214,15 +210,11 @@ namespace Perspex /// The scaled rectangle. public static Rect operator /(Rect rect, Vector scale) { - double centerX = rect._x + (rect._width / 2); - double centerY = rect._y + (rect._height / 2); - double width = rect._width / scale.X; - double height = rect._height / scale.Y; return new Rect( - centerX - (width / 2), - centerY - (height / 2), - width, - height); + rect.X / scale.X, + rect.Y / scale.Y, + rect.Width / scale.X, + rect.Height / scale.Y); } /// From ba95d1f35a9a5e6de201b806dc903080fec18eb6 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Mon, 14 Sep 2015 23:52:58 +0200 Subject: [PATCH 06/20] Fix intermittent Perspex.Base.UnitTests failures. --- tests/Perspex.Base.UnitTests/Properties/AssemblyInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Perspex.Base.UnitTests/Properties/AssemblyInfo.cs b/tests/Perspex.Base.UnitTests/Properties/AssemblyInfo.cs index b011d2a1c4..1752a3b211 100644 --- a/tests/Perspex.Base.UnitTests/Properties/AssemblyInfo.cs +++ b/tests/Perspex.Base.UnitTests/Properties/AssemblyInfo.cs @@ -2,5 +2,9 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Reflection; +using Xunit; [assembly: AssemblyTitle("Perspex.UnitTests")] + +// Don't run tests in parallel. +[assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file From 3648d5b822e5661ce4db36f71920b78446f1209c Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 00:29:09 +0200 Subject: [PATCH 07/20] Fixed cairo Path tests. --- .../Path_Tick_Scaled_Stroke_8px.expected.png | Bin 0 -> 6459 bytes src/Gtk/Perspex.Cairo/CairoExtensions.cs | 5 +++++ src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 11 +++++------ .../Media/StreamGeometryContextImpl.cs | 3 +-- .../Perspex.Cairo/Media/StreamGeometryImpl.cs | 1 + .../Path_Expander_With_Border.expected.png | Bin 1311 -> 1281 bytes 6 files changed, 12 insertions(+), 8 deletions(-) create mode 100644 Tests/TestFiles/Cairo/Shapes/Path/Path_Tick_Scaled_Stroke_8px.expected.png diff --git a/Tests/TestFiles/Cairo/Shapes/Path/Path_Tick_Scaled_Stroke_8px.expected.png b/Tests/TestFiles/Cairo/Shapes/Path/Path_Tick_Scaled_Stroke_8px.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..355edf84c22f4c4b2b4b4f644d49f56f40ce2748 GIT binary patch literal 6459 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 O&fs0*<1Xa9v;TjC((*R| From d4bc955b3801894ff324cf48a51c9f830738727d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 00:31:38 +0200 Subject: [PATCH 08/20] Fix expected Rectange render output. --- .../Rectangle/Rectangle_1px_Stroke.expected.png | Bin 628 -> 609 bytes .../Rectangle/Rectangle_2px_Stroke.expected.png | Bin 619 -> 611 bytes .../Rectangle_Stroke_Fill.expected.png | Bin 620 -> 615 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/TestFiles/Cairo/Shapes/Rectangle/Rectangle_1px_Stroke.expected.png b/tests/TestFiles/Cairo/Shapes/Rectangle/Rectangle_1px_Stroke.expected.png index 6aa013a894afc8d113567acc51767728aa94e17a..24239d5799ab3308d44bf2ab283758dc0202c9b3 100644 GIT binary patch delta 110 zcmeyu@{nbMqXoC8i(^Pd+}q0=1)CiNSPr)TDRw(I^9slBRkv@ll<_fuz=5FaIhARN zi}iU`8aG_MpMQVz0q%_xw=+(Bz@^@jz0GFxhKtkLz$zK0Sw3ffb%QnA_j}nTkcg+N KpUXO@geCwrel2JK delta 129 zcmaFJ@`YuBqnn(ki(^Pd+}q0sIS)JVFgRNGvX)Of*JFM9;7>`j3C~m6T0$Dim>EDI z;!557qQ0HaIK3VM%xNb!1@J z*w6hZk(GggiPzJ`F{C2y?bVIE4Gugk2iyNuvng7}DIQ8!+sU@)6BAGi1H+9ghSBRH zZv>hZoMV!=l|Le$Xukg4E%rtQ0S=~7Vu*%8!I^2VM%xNb!1@J z*w6hZk(GggNz~KDF{C2y?Nvjr!wv#02PgmkpDuZL*>$E=yH%5Z9x&St)Wg8=BmMfD zbGF>-x63}vWR3e#D-hojY{`Z6 W#q7DC*bgd#1Uy~+T-G@yGywo`EMoxx diff --git a/tests/TestFiles/Cairo/Shapes/Rectangle/Rectangle_Stroke_Fill.expected.png b/tests/TestFiles/Cairo/Shapes/Rectangle/Rectangle_Stroke_Fill.expected.png index 2eb5c946cee0c765bd2948e8172a1f4c3062a8a4..d1c13a9e57f842dc1c881f387fe80db1d00510c0 100644 GIT binary patch delta 121 zcmaFE@|$e1{EqSR8Nu|G)XthJr+$rYWa$e1{EqSR5_?|KEIhgGZunQ;A^OtltdcF$^H^XLEMh z^Lee4bFC}RGV$;GrErf!{g*|ZJWHM8#))egCq59-C^-A>&gOzmx$JfvU@Zm9w%)tc Vz*-dhXy$*AfTydU%Q~loCIHbwFzNsR From 15954d1dc5ac605863d01c104635286cccb6a004 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 00:32:15 +0200 Subject: [PATCH 09/20] Fix intermittent Style unit test failures. --- tests/Perspex.Styling.UnitTests/Properties/AssemblyInfo.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Perspex.Styling.UnitTests/Properties/AssemblyInfo.cs b/tests/Perspex.Styling.UnitTests/Properties/AssemblyInfo.cs index c17aed34e1..e45f18c082 100644 --- a/tests/Perspex.Styling.UnitTests/Properties/AssemblyInfo.cs +++ b/tests/Perspex.Styling.UnitTests/Properties/AssemblyInfo.cs @@ -2,5 +2,9 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Reflection; +using Xunit; [assembly: AssemblyTitle("Perspex.Styling.UnitTests")] + +// Don't run tests in parallel. +[assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file From 1322fd11d0f1f2fa9cf104e7ca6fc7d0cd16f906 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 00:49:04 +0200 Subject: [PATCH 10/20] Use -1 for infinite width in pango layout. --- src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs index ac71e14e02..509ace45dc 100644 --- a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs @@ -45,7 +45,8 @@ namespace Perspex.Cairo.Media set { _size = value; - Layout.Width = Pango.Units.FromDouble(value.Width); + Layout.Width = double.IsPositiveInfinity(value.Width) ? + -1 : Pango.Units.FromDouble(value.Width); } } From 66c0a50876655216695a503f4876616e3b0bfc09 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 00:49:36 +0200 Subject: [PATCH 11/20] Coding style. --- src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs index 509ace45dc..b61a6c6c15 100644 --- a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs @@ -12,6 +12,8 @@ namespace Perspex.Cairo.Media { public class FormattedTextImpl : IFormattedTextImpl { + private Size _size; + public FormattedTextImpl( string text, string fontFamily, @@ -34,7 +36,6 @@ namespace Perspex.Cairo.Media Layout.Alignment = textAlignment.ToCairo(); } - private Size _size; public Size Constraint { get @@ -52,7 +53,8 @@ namespace Perspex.Cairo.Media public Pango.Layout Layout { - get; } + get; + } public void Dispose() { From 3d845f95272a06c4f0f901423319ad85cc19f159 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 01:42:09 +0200 Subject: [PATCH 12/20] Fixed failing Border render tests. They were failing because passing a Pango.Context to FormattedTextImpl was a hack. Create a pango context on startup that can be used for all FormattedTextImpls. Fix the expected test output for tests containing text as the expected output came from the Direct2D renderer where text rendering is slightly different. --- src/Gtk/Perspex.Cairo/CairoPlatform.cs | 19 ++++++------------ .../Perspex.Cairo/Media/FormattedTextImpl.cs | 4 +++- .../Border_Bottom_Aligns_Content.expected.png | Bin 797 -> 761 bytes ..._Centers_Content_Horizontally.expected.png | Bin 830 -> 760 bytes ...er_Centers_Content_Vertically.expected.png | Bin 811 -> 771 bytes .../Border_Left_Aligns_Content.expected.png | Bin 838 -> 743 bytes .../Border_Right_Aligns_Content.expected.png | Bin 800 -> 734 bytes .../Border_Top_Aligns_Content.expected.png | Bin 801 -> 758 bytes 8 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/Gtk/Perspex.Cairo/CairoPlatform.cs b/src/Gtk/Perspex.Cairo/CairoPlatform.cs index 5ddfe1eab0..f25aadda95 100644 --- a/src/Gtk/Perspex.Cairo/CairoPlatform.cs +++ b/src/Gtk/Perspex.Cairo/CairoPlatform.cs @@ -17,6 +17,8 @@ namespace Perspex.Cairo { private static readonly CairoPlatform s_instance = new CairoPlatform(); + private static Pango.Context s_pangoContext = CreatePangoContext(); + public static void Initialize() { var locator = Locator.CurrentMutable; @@ -36,12 +38,11 @@ namespace Perspex.Cairo TextAlignment textAlignment, Perspex.Media.FontWeight fontWeight) { - return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); + return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight); } public IRenderer CreateRenderer(IPlatformHandle handle, double width, double height) { - Locator.CurrentMutable.RegisterConstant(GetPangoContext(handle), typeof(Pango.Context)); return new Renderer(handle, width, height); } @@ -69,18 +70,10 @@ namespace Perspex.Cairo return new BitmapImpl(pixbuf); } - private Pango.Context GetPangoContext(IPlatformHandle handle) + private static Pango.Context CreatePangoContext() { - switch (handle.HandleDescriptor) - { - case "GtkWindow": - var window = GLib.Object.GetObject(handle.Handle) as Gtk.Window; - return window.PangoContext; - default: - throw new NotSupportedException(string.Format( - "Don't know how to get a Pango Context from a '{0}'.", - handle.HandleDescriptor)); - } + Gtk.Application.Init(); + return new Gtk.Invisible().CreatePangoContext(); } } } diff --git a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs index b61a6c6c15..81ae567817 100644 --- a/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs +++ b/src/Gtk/Perspex.Cairo/Media/FormattedTextImpl.cs @@ -15,6 +15,7 @@ namespace Perspex.Cairo.Media private Size _size; public FormattedTextImpl( + Pango.Context context, string text, string fontFamily, double fontSize, @@ -22,7 +23,8 @@ namespace Perspex.Cairo.Media TextAlignment textAlignment, FontWeight fontWeight) { - var context = Locator.Current.GetService(); + Contract.Requires(context != null); + Layout = new Pango.Layout(context); Layout.SetText(text); Layout.FontDescription = new Pango.FontDescription diff --git a/tests/TestFiles/Cairo/Controls/Border/Border_Bottom_Aligns_Content.expected.png b/tests/TestFiles/Cairo/Controls/Border/Border_Bottom_Aligns_Content.expected.png index 163e53293fc42a63090e5b3a09791835bf86ce72..97ad2127019cab5521f2e18160fd8abd650b2239 100644 GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyD!!coe${k}9u$q-*SzP(`7@7M#h9+25ad2&&-vu`pQoqbvUKezArishE?GVM%xNb!1@J z*w6hZk(Ggg>A0thV@O5Z+nWb{?>I;_TvRQ6A`-;*vRN$1ON-OAz)j{wqs(QtnVmT) zieC<@DIBQs|7Ey_KjvBV`4j9w;}{qk=2}Irdz!cNkX$PB{At=B`kx6O32xb2d2QD> zmPQ2u4yI9JkcC0PrkK-r|MK7HJbUOon~kFa2TPNKf{f^i>xRXLx1BpGabxr1`3l>U zpEcH=`}v2V?2H)qp>7tV?NPVaUcWjc^ltO_ymdF1-`USTGkwC&qfuw?*Z2Q4ORM$& zlzryqjOFiYXUZRtzNzyk=fVDS3dIxS`+pjyncDxhdzR*Nx4Hkp)pH8-r@u~qCAUZ2 zJ%6L#@tp1MpM5^wFw6QE`~89L-dkd?7j8DRKYr%FQMzriPbt4$)0*^;-?{H^x2xV1 y`Qv88cLf0!riVA9b#7=z>wwZ914F{=f*;J+jZAx%e2_c<67Y2Ob6Mw<&;$Sx0qU9n diff --git a/tests/TestFiles/Cairo/Controls/Border/Border_Centers_Content_Horizontally.expected.png b/tests/TestFiles/Cairo/Controls/Border/Border_Centers_Content_Horizontally.expected.png index 18ecd01c7a707b53da0ef2d890604cd900c6658c..77a7601e1348985970742148a38a0d56bb43d6ea 100644 GIT binary patch literal 760 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyDDd^)E+vHWA)s?x=e)(d7jZ+<^{0>krzjQ@)SB$v|g>_?1oIjk)c( zF4k?Y>9*G=WtzR$xCb@PiMM+kemq9{_Q#OEq|Dg+Mds_P>)$VM%xNb!1@J z*w6hZk(Ggg>4m3@V@O5Z+ZzXaFFPhBWn?|xYI zX7kH^+nOB&I9M7T1Wt(7N+nl4uoZe}; z`Fx`8^TVZO6SSqxzu(vXoY*rzxkmDF#;-S@CH5a%Q5@6mkay*Gs@>9ag|)M{Dcy=V zF!_JdT3ffd*5+y7EZ01(*>V18-HVC6tTBIQe}66UIsDnjU)I^rj~V`!xo+ZH-!rH9 z&qUq(sYjRQzbZ70>8~}rd;OlH0tZWz!zeL0!{E?oqv_LA+p4GV-Tmu=3!`)_kPMm^4HN7**d zkB{AJ4BpCi_Q#hlK4P77nA3y*^Y1HTaO*DGLEybu-9g+zAP5A)@*QMb{|{lf2TQjG zJClI|ev?oFPAS-3F!y-1Rltq1g8%>k0002Mf9N}#*eKxk&2vlu0000VM%xNb!1@J z*w6hZk(Ggg>8huTV@O5Z+nbJlB90Ob7bVX>^s;5Ub6C4V#D7tGfp0_wdrVdD##1Ge z`xNDSJQ}|3eX=~E>fo|{FJFCO1e(Xdkg&Y(bd=v|uIeegdm_Ug=%2Oj*v(P>c|q-4 zJ|;&60hZxFJlwJ7X~}QqvZT!)H#3$Ca4 z7*a9k?X5(=M-B`P7Y|m5oPSokr$>(M{iVN(Djr{oW1i*wz=W;Nw#-&Sz;gbcg^2h@HRKae0%l5uw~P>$g(s!DAZ_AxO?;CmZLon z#Ap8FFWMrXY?EUk_@nnul4FGGgzF#wU3;Bc#FKZ>=vc(G!>?a{tSS2UqptqPp8rX2 zvi7sxlezxUDt^lx-9JxrF3z7(9Y?#}y}z>F%(CY==6^S7 zuHK)I2TkYqt~E5=aUewDvj68Qv2N+&m`n4XweD9H;9zQ07$pX27;KomBkg95Sb^=$ h23Zzx`eOL!Tn|jO3tY^m9=-??@pScbS?83{1OOxT(y9Oe literal 838 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg>4T?>V@O5Z+goRIuLMXq1h(_~9%!1sD5EiG1WydCUVFOs`fkJBR_x0Y?gsWw|D3+REc|uP+iO2>zpa=z-}wIScXyVj{xl1-SoSq; zkHwx_YxgzV$bPOnv)XX?&wHm0<&VddzB|0hCgy%a^}F@8?3G*Aw%f!_dw*N;&*y9G z$0{PXM-HoenOFHy3a!?$b1XPN(4=HVouv@7v=ocoy+^fnu7)8rBPyVhJnTHYeoCk7IbZ5^cMi9 eQ-&Y!bx!-6X>_?Q<`GQ>33(My-{9|m+(HvNSm;aJ0i_TipO!PH zFpj(B?AfD7=68Gk|GNG7ca5x^HFK_Si}>IjCSX>c!)m#$_g7xdjiis$LlnBxyPAvp zdV8mS{xxNL<=*b2X?j2Orfsi$xSWN_Q9)po7_4DXrhRUv_Y5i_2A}*C4*9tDnm{r-UW|G>xxO literal 800 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg>6E97V@O5Z+glfNF9%38T%6)4ki>T{QB*8}eMXC|gUtr!B;iAQr}AoM z**QgV3!R%-cUNWGrzif`^L8-f33q>l)G(o7Nn#{g=XS`84Lnk?nWi zz23nvUpHU=&4Z+E%?Ea}FgYp+upByCVVY)Vu;z2#nQJVETz?v*{kxiRZuZZE$3XHi zd-{|4^7r2BkG#6^_@;LmAFiLd?-=)Qk63>CoxHdEb=E((io0`8^Z2t}KAV~g0{P}U z#`XNPdG>Y2^W?Dn<26#j$Nf|V)?K=sy4PRU`nYGbU{2=VqqDZVKTi5%csy_Mv)@)` z*Hh)*T-?WTu2g4&<$jysJC@IHY-~P%sb<6fxnI5gEXBMkI1E% zVw^(KPnt=JA-y;Yu<~PcGbq7+kaHwtqnX7l-u28FW&i*H0002)({5qT^VL@Y?R*|j$!<147TpC?;tM^`_t*?DFKevvC210h4e66e$lE%zeJvDqy4RAOHXW e0002+ANmd!s3za4rCZnl00006pm}BM_i{FZt8Zy_ijZQ&pJ* z000000KiV2E!T3hTw#y0fp^OlIO4%8h-HL5*}V8x5cpRDfqx(n2qy*dam?JXt#dsF z_Uz;p1uW>wGNwVUtkeeQk-nP-r>#ahk3e~D$_dWYCZ@>%Ly!hF`qs}1nCI3F=a?EPp`!eRon0f|p!Lyw~-Y?f<>KVKy zCvUO7j@fRH<~^C>*fwhZU(etrJ=+%RZ=c3ojhUY^XFX#~^$gyEtY>lih3{LRJ=whY z*?`|cAP58=Y3{Dkvqinzm0ssI200030ox|Y| X!&Nnm!C(Q>00000NkvXXu0mjfOO3ST From 092f03ef7bd8a29a1bcdd89b481e83095ff7ad5b Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 02:03:48 +0200 Subject: [PATCH 13/20] Updated coding style documentation. --- docs/contributing.md | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/docs/contributing.md b/docs/contributing.md index a8dd7cf6bb..f601422f05 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -2,23 +2,11 @@ ## Style ## -The codebase uses StyleCop with default settings[1] to enforce coding style. Yes, some of the -decisions it makes are downright bizarre, and are certainly not what I would've personally chosen -but the less time spent debating coding style the more time left for coding. - -StyleCop should run on each build and give warnings for any violations. So please, follow the style; -you'll get used to it in the end (I know I have). - -If the .NET core team decide on a style and write an automatic checker/tidy tool for that style, -I'll gladly adopt it! I'm certainly not tied to the current style, I'm just tired of endless coding -style debates. Someone decide for me goddammit! +The codebase uses [.net core](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md) coding style. Try to keep lines of code around 100 characters in length or less, though this is not a hard limit. If you're a few characters over then don't worry too much. -Documentation comments should also be formatted to a 100 character length to help keep them -readable. - **DO NOT USE #REGIONS** full stop. ## Pull requests ## @@ -45,8 +33,7 @@ unless you see something that is obviously wrong or that could be written in a m idiomatic style. It takes time to review each pull request - time that I'd prefer to spend writing new features! -Prefer terseness to verbosity (yes I know that StyleCop will often be working against you here -:weary:) but don't try to be too clever. +Prefer terseness to verbosity but don't try to be too clever. ## Tests ## @@ -67,6 +54,3 @@ English what the test is testing, e.g. Render tests should describe what the produced image is: void Rectangle_2px_Stroke_Filled() - ----- -[1] Documentation rules are disabled because there's currently so much missing documentation, sorry! From b0401f5c712784e08029b567e7f3e296ee17ec7d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 02:16:03 +0200 Subject: [PATCH 14/20] Added brush tests to cairo render tests. VisualBrush tests currently ignored as it's not yet implemented on cairo. --- ...earGradientBrush_RedBlue_Fill.expected.png | Bin 0 -> 611 bytes ...VisualBrush_Align_BottomRight.expected.png | Bin 0 -> 928 bytes .../VisualBrush_Align_Center.expected.png | Bin 0 -> 924 bytes .../VisualBrush_Align_TopLeft.expected.png | Bin 0 -> 934 bytes ...rush_DestinationRect_Absolute.expected.png | Bin 0 -> 1426 bytes .../VisualBrush_FlipX.expected.png | Bin 0 -> 2152 bytes .../VisualBrush_FlipXY.expected.png | Bin 0 -> 2176 bytes .../VisualBrush_FlipY.expected.png | Bin 0 -> 1653 bytes ...sualBrush_SourceRect_Absolute.expected.png | Bin 0 -> 3321 bytes ...Rect_DestinationRect_Absolute.expected.png | Bin 0 -> 2031 bytes ...eRect_DestinationRect_Percent.expected.png | Bin 0 -> 1996 bytes ...isualBrush_Stretch_Fill_Large.expected.png | Bin 0 -> 13946 bytes .../VisualBrush_Stretch_Uniform.expected.png | Bin 0 -> 12243 bytes ...alBrush_Stretch_UniformToFill.expected.png | Bin 0 -> 13274 bytes .../VisualBrush/VisualBrush_Tile.expected.png | Bin 0 -> 1723 bytes ...sh_Tile_Alignment_BottomRight.expected.png | Bin 0 -> 928 bytes src/Gtk/Perspex.Cairo/CairoExtensions.cs | 5 ++ src/Gtk/Perspex.Cairo/Media/DrawingContext.cs | 8 ++- .../Media/LinearGradientBrushTests.cs | 4 ++ .../Media/VisualBrushTests.cs | 64 ++++++++++++++++++ .../Perspex.Cairo.RenderTests.csproj | 2 + 21 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_TopLeft.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipY.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Absolute.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_DestinationRect_Percent.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Fill_Large.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_UniformToFill.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png create mode 100644 Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile_Alignment_BottomRight.expected.png diff --git a/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png b/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..9d11e8b23373c7e05556c8c90f48fdc6f31a7195 GIT binary patch literal 611 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyDzopr0GL;M=Kufz literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_BottomRight.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..0918b7fd511a807b03c40468527b049a248172d0 GIT binary patch literal 928 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg*~`<#F{C2y?OoeGo&dpA`H+TBqo|&JE-Y8D~ZrASq>__)${f~;9j@?i5eel-B-zf2O z&9>Vo=cd%}&6|DtbJ4k~IUBT3*=<|C-?i+0b9MCRZx5ak8z}H@kI78`pVd!2uRYoO z<+RHA?QDu5?zHiXBotE~evZgw{efmG`Q}HJKou4fJe&k3^ z`fqm9_SC#wwYs+rqAXn6C;r*I5`D69L(_qJ2bw2`#zWihyzAHBQM<3^v@RsQZz#3+ Y!>exB`>J;H%|{?1Pgg&ebxsLQ00#PR6#xJL literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Align_Center.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..dc6050fec427d190178d9e4ea227cfcec9e4b8cd GIT binary patch literal 924 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg+0E0%F{C2y?OpqI(xEb}57=ifXq=?Q5yrSB#AQ(m_mlu9PU{9C&Q(+X zM6z;dd1XYf{^@($t#<9RW`WF8-+lg8Ge1_;%zbkAvGrt;eat`$hy!vR;eNMme?8yw z^yiJIF;!o;u)f>)Tl9!gQS@xi6xPP+y-f}a6#_IkM7Wq*Y03N_yzlc5oB6&s#94P9 z(w|(z|NGSBljnuMIXli<$gfr}SN{Irteo)as;kdDJ{eVb?)>jkp-R2V>`9L+&t8*K zj$C?XV}9Rm_R2LIVv2qw%#Y8T)MKlC;%M^C|1Y=vfBEF_*?-@@PksD)&z^4=GwbJW zKX&@#djH?IKYpq?H#_NHdE7VSv~#C7MytKA<>Ei{kbS!RBi&8M?x*=acvDjp2op-bz&V+noEo_Iduyv-9hx$0Wrjs=W+0e)8D!kL}Oe zO?r*@X2g8D`(*V=tMb^Sxu+#0jW^Y%Z;Jc;H>L9Lmbr&M@MxUi-D5V>|L5{klh>TA zez)Cop8rF;Q;pSUP8CQPZ`vDj?oRO@%b$gleoL=gtYH4(o67u8uh}eb*Ic@`CcUEC27P{&BoPALx0>>b=*iC!bf3_p>|6xNebx`6T~8KG%Hi<$V5Oci->Y z)1YnkKGSwiw}^>)x^qg>S|Lq`Cl!-UuPj&BynSbme9Bg@g@5j!DgE?)clgdv7XLmm zq$d40JZXEXJIA=O%yRk~g@6dh9bKXVM%xNb!1@J z*w6hZk(GggIl$A!F{C2y?cI%&bdqIQKRi`cX<4+of@_J=s+KrM504Yl0;`mS9@(+F zs;GPv`E&kE%_`rwGPBR*y}x^Z{i~esCEsg`^L^+4+*RJZlM!e>14D)5-jXP@`uWrD z^zYuIerNJ@fA0rkzfXOi{9L#qWA~mTRr#Ne7k+(q{$yEMq|xabgGl3ZKMVK!DE*#fu6A?Y z^PIJYlR{7B{QkA0YQk}@)2i+K-+mTOO?flZQ7`ZGFaPCV{ng&*U)%nFT~7S*r#sL4 zy?(vJG;UjcY1I9`>3=Qrx_-Vdj66TXQt$S*YT(-E{1J+S~)Tg>6rA z&i)&j=l@RS_3O&pbL6KdUwhoMw`+3F@e|ok3ghzM?oTuOUtg9o{kwv^@1yl6^Cy>b ze!2BzQoee;-?fdeg-(S8rW(!v^k36|li$7K z{eGM5TYno!=NTFwPCRqsQ;=ox`H#Pz9QS;eUoopJc7nP3&nfZdCnBFs{%5w6bH7P; zN?L?^W!lX0{?+aAY&CT;wkK}9-g<9ljoHtnPlaY5RNn4VnCSm!&Kk?g&1W9pt}%|B z?j8BhAo5wv;(_i0{%f0=#r0q3fR=@X70;@RY%M*AcIOm*-6=x)CweZOe8a+&}* h!BUH8xVv-bPxjqcdS7jjFq{E0)zj6_Wt~$(6951jcT@lX literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_DestinationRect_Absolute.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..9253eee16411dd2a474037f7f1b31ad03c64da65 GIT binary patch literal 1426 zcmb_cdr%Sv7^i|Hj3y^)nkgw!Qj^fqSfF7%H1kou$c(H|>uk0`={TGk&Mv}Cbc&vY z`O4cN?92y3rmb5Il%eUCDL6I3AcOhmO$jlRe4`b`j#QF)iNWj zNx(4;*plb??W>I(Tr-yC1iCn21*sL3tmP4X3wqVp63&>J-U+!Mz37UJJf0brx5u*E zdPIPKbg&!?!bVI4W5~%EYTxil{~Sza0JlA(2Zqe~F3(M|_WJaiMK5*mo$&6d5y8Hh zrt@2xJpFPI-J=g%o`8qMY)UEq&)0Ki;~#hrb=$RF>A_l_&!$HiRefB|bVaVWw zJf7a{H`ifxR|J4+|r#TgyGBQY;bo@ z^(Bd=V9F-ggwb{I$T^1Gd1JVON1IxXEtMWpPODsZgUfX%h-lLVJD__!^Q!=omSoR{ z!1ahhSJ0@k8}uqMe&sZrF=u()AdPiG$(vw|rxM4Qdc-Mt6E}V<)WzO{0Z+Zq^gTO5 ztRjbSQ|B$(*DhYQcM)rd+JV+=@8$j?T#cOIU-dTB?HE>~->;7Pwxh51>zB;pCd8Ug zt*Je6;jexOoN>nRIX=`xmmMwf3e-Pi>}8cMX>z8!+63KSrtpJXyvk~>e?m=HQoqN6 zf3i8ToW~+ z>@++W_b&}mv-4`q<&!aF8Od_7?SMh#8!U14!aY4U%Zx1Rs5@s0v ztQLC@F@w0md?_9P=3?&uc+t4(?oDDQW%)WYpHIEWW>$#!Dg4bpJKs~iQLU;5GcZ*t zBjf0dsExfEw8BYUufMU`RyT3f^1jPM{hsxz4gFuzj+K=!=Y~*2xRd7?rmH*Iu>mnb z8vdP-+xxS>U}`)`#Ia#I@!g)7D;i!dYT-&%8csQVHo7a2I&wP$oq{@4$!&?#fksQQ wpjJ0W2pss)n!?n1CF%Vm9sc=a1%!5;Z9_#@erLmzO)DRu2y!$@7M9BW8^BFwzyJUM literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipX.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..da7003b4193d8dddf07ea6a7e6eaa6600c0fac97 GIT binary patch literal 2152 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(GggL&(#`F{C2y?cI%i(y1bC4_jw@2zzM-?C5HlrsXl^4pVASo6*kZ042w% zMvbc#ytKSBibM2l_Tt2*ZiRkrxO%;-sYo9vZcz;>y?>8=`z52{btZXh^JRKqu0-6R2K?x2^ z4m5Z)GEQWookYQ7#)tJE^j;@UwbNVk^VZIS%VveFKNolX=f3xK&8zQPwK5Ue*J|c5 z&k>H^aI!z*e#qag_xJqTo%L3>wR}$g>Kn(uecCZS^nu~4(^}s?&slkVfz^~Zzccsm zJp9+2OQ(2dZNj?R`Nwz3f0ihi|M$zL-&|F9&o7MNmV0gZ%R;B0Is5Fa`Kx1Bygu&P zwej`cM=$KQ)m!J-uh?b3?fLto|Lppn*A?D)_qfXDo4sw$`HvNI9%pU5CwJT|xk%=> zU*w)|I^X7Qnju`A+;>-dTjkq#qI+NNyu8_NUG>%ejr->xo^dxgOV0fG;~n$T`;V7h zzqOA)vZr>%{~U9H=6Q>%{zTR?U0xC=vPyhHw3MxQ)7!dxYn~R$T>k$2P*5>XT=VZe zarSkmW_|u|A3xdBDE!^|djXsOZ#J*p@Bc0GwBfHEJInswcw>Kl_UHGjR*%oL|!%AA7Z=mRq}7;YeLBeYCHa}S~dT3cIfWf9cx>6N7!zkr~Sh5 zd-J_Bak8)f|LHg?wL$E-ft&p48EXt9K3DP;_~jg2_Ww-v>Q(nr?`6uEikDP{UOoG_ zPgeVtY>v6w4qGulyYBk9uZvdMYsU*cJ91}6a{c}&YtQucFYZcJ-K|aGy|y8(IH$`n z^0Dsi5{GvoAN4MC--uVZ{^97y8==kRN9|5lw*Ri$zw>v}kH>Yz?Hhk@eHUuGsw(Cy zv$Y;iaZ=uyi93^S##ddApZ8L7FZ13x;kP?Y6Lhbg`B!xM)}~|8+g>&_l@ zbEbB2+Pg0cemA}ov|U{OX8H6lTQ0u7S$!?(Z0YqP?_K5piFORM%OTiv;f`9i T=j8yl78pET{an^LB{Ts5Q26?0 literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_FlipXY.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..4bfcdb2dd3cafac0231e49782abfdfe0a9ac0eea GIT binary patch literal 2176 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 literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_SourceRect_Absolute.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..e1fcdbc1a6697a32ce517e6457612c1ecf1bb68f GIT binary patch literal 3321 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∓YWw7mj5JWIy=?S7D384 zNCW1$UAjl|x~_g;jK?H4H5C$>ZIG>;CEX$2E7>Sv5G4*u?AItPWwk-h1e>w;OBlt) z{Ps|MACjJwM!ckEPHd16Xg2PXm>y;s%aUOO(-G;gG~+&vsjxx1K>Br~gjpDuvgMa0 zAXFY=ZR#RD zV*4ukNMiPh^l71KQx|NIIict$9m6o_9I5HOU>+s`Xka3q8$#5Zje|L)sj0P?in2gy zi4Ono67FKr;yspMSYlpC^*Sky3T*rORZ6s-0# zGVW)Yz0scmT*645wvUoOe`gAplq{|a_HFX#yP0Z&?wPw8QC@M9c@K)~Az#Gx!Ty6r zrkY>v;S2=mT^v5%*Te8wNx%7}Kp5=B1G+a%b>1Ze57E?c=6|eiFifL93vX+t`-u<5 zS0#e8C1 z*`tsA2(g+why0;0H_A_FkC#vpk4sODz1Ds_+g)gp?3N1O1K96AFC!dUgm!Ce5EszAYh2#6`WMhu-4B!n zZ>*uCnbKWxV?|`@HJJmTFlly^@fIPhavYOM`uDU~vCIJitE9Q)7`oC*{S9l-u=0j| zRIj!kttSQiRohglp`pE+ez5ZXqq})tkdEVqVDc+?!{{}5ukqwUIznhVjZ$?!Uo77> zlj!MVJw!j!9mbJ&<$m!G!J7jOZuU-ua%ycp+%-;#8GY)BFX_{ew(j&hWZVM^ z{idf>i2)hurmJ-BqP|)trFgR%tBSVAy0I?Fu0uLtLwVxr$5V!8i4oa9Wyh{VYFC*! z1Cn_BK6XrUF=ulr$DhBgN;nV!u+)mkXb_V-#f*cw!GFHHesodciEGJPx%Rm?Y2imF zO%Zt1?Cs$yOhJOX1X+DrHxBuY4Gbe)lfjbx=Ng7mbO zHU*vz7+=U+JuzF$q8eyGnQ|oM>iv2Gu)k%U=Q_`Bn*B2i?c!AiX=KX0<5Uy$NUVC`f^1hK zK*wh`p9q})rkeht+~IcWhg>hlNwi|G0Jfbk#x>mozA|CKr%T5iHuK|F4rd$pB`mZw zA@QiojVEjDb}ha9Y!`jER0lpPs{;?RAs4ZADr;nKQ?G93dqcd-n@N4m$T5p9&|HW7 zt4n_t&DaXwjL5#Dl0peD=0o0j=+|>jkG&V1 zr)H4=g$%5c1741qgdef*c6)g+io3M8jjwG&^poUrkmTsp*G^B<)-ScTmuy`h!a0Nn zKn9S+o_Y+hM0e^UukdHZQruV-g4mZuCK)UnIAVSf5w12iZ}fZE*j}OOL0HfqqMd%$;OY%Uhi*Y4pD)EbC%LZL~bOTdRzynR)0j zwXh4pA{Fi5zRgitmafY6zAC9HV2~ayRDSk+K6QrUEqM(b)1e&YVi6O!eUboeX!VBt z5*UPcZ?(yG+M(bcpM2wIUXir*hevKkk^EtyiDyU+0>oUGDVyW2sa*d|r#aRW@U`erqvziGxp8=DaS`xl9qqIg%pI5LrCJRS6X)WyjI J)#MOP_%FKVk5T{t literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..1aedd35831100ebfdacbde93529d21e50629d698 GIT binary patch literal 1996 zcmcgt`#%#38)w>RC}|VUXfMi`<M*(l@)lj{GBWZv9dKA;tl!EMx{7oI z#-})@bf%?&tNipu_SVU(z-pl+uqSJcz#Jb!T()6b9aZ2 zU?+R`fG-^4@Z&7Y$G`iH*S^0YY!W*Q)&$0a;)?{sq?R+7eTWHtGC}o8P7kIJSN;GS`Mf`Oc4wUma;nX zpO|6}R`&b97`AkeC#^5PQbYm(= zc_YwOQ%cR^+KO=bX%wXAJ-6&JNn5~q-5Y%WFyn!UYjYP%tG)oDV1H%71RN&cR+urf zVsr+QjYZ@Jgh4afwEU41zt;$7uOYR$yPijYW+n_p9x7d)(?^EYa5bnoVvn2dWS3+U zkcLG}4YU1R|89@vR#+U~I$5buey;EAd;z~L*ICHER!WEBMW>i->bGM@_hWp%BG4$; zcik)u&A=V*cVLs;S-_?~`lA9ykaX1oAU&NBwTvsZTx+Y>ww-6=>R);ryl1)+;dilV zJUPNz9qU}y1=eE^?S4*J876Jc{W3njrgeV2eN6nebukEdx`8ev{pmfrWOXjkYl_%} z^wTe-of`GzvI($}7WzoQ=X^E2f@)O8@s3$9v;?syLfZgU ze|uUmF~^VvZN5h6OZ7`0Dn`hTN4zPcQu-O(^so~pn*Hiq1x6<*us;68nki8AzJGjL z#L6W;0Ai1uR!fdxaQRBZDZL<3;?kYEm8p0PFp`elsgIR$plp`$FhzjOwDFp~JkN{@ z3~SwSXXr3EBx%v_3!4|!jmVWA`(8Mne_k4mvUOV*vgtr+7>n>hKom^mfvRu5MB@}7 z_CGeiJu-z{KWhlqd-%|}45w^9OgRMB(*&2J_bX>%QUGwR0YeY9{OcA<3ekLK_S2;k z;5#d;UG-D#cHuF{t5g%m|H}3Lycu2_hse#4=ux9<<}OrXbaqZ^4HY?xJd*&KRlFto z5TQ37pNyN6e`NY-qzJs756Ju+WWh>+uA+ddBZbkpUBgN5Q7o-xH{5U6=F`T%R%X7) z>xwBBtP91+6QgL73;ceOqg~@dL$pyQAhVzDh5y>b-`=3!CaVEerzS)h^I?;YAW_%k zX?y<{tp8lR6FPZox!-v#DAx+qsPkroo8AcT!e7HKbEzh1TU+fI%fezO!?5q92vy4{ z9$(s4vnuc{HF6e3c!Y+d3=CCTJ#9Ya%nXk_T}`OydU=*C1vbH(uq~D0eH;SsxMkE5 z<#gM_EVU5)q;IU#dIYh5L7(}L-y4H_W{BKUipNrhYhW91c)fl7Lf9u=IY^I69BG~* zfw*xie0rQ81u3caPn!0WKM-U}AerW|FY}6-EgA(2yG(U3Ouv zM=h_CT7*{vUx#UeLyROY!&exGrM&-JwuKMV;wZYngJ-@bI`3;cF9ZwMR+PIN+?9_3 z=qC1uE5+~xwZz+VwXQRlI4LtwsxhFcdBC(8B;6Gmsj_h>;QE8(ebXpsT-Z_LZci^@unq)>QXF>NLLvo40WFm<*UE%9T6$Akg;Msr&8Lq(Motv5NNd{GW>zj8&TNi uXbv%6j0@_dm>%#QH#SuH-`h)~kegT0$On1+YekLT->VL`PB@Nr0PVki{DaW| literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..f1914a404f30ea4e3549e6e34eb74214e5c0cd31 GIT binary patch literal 13946 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 literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Stretch_Uniform.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..fb2ae9f8ccbfc5cd2d8f66120f35e4fa0f119bbd GIT binary patch literal 12243 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 XGZ~2b%IM@+- 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 literal 0 HcmV?d00001 diff --git a/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png b/Tests/TestFiles/Cairo/Media/VisualBrush/VisualBrush_Tile.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..64695d4bb16c46f040557676c8a781de4f4be10e GIT binary patch literal 1723 zcmcJQdsNZ~6vvr`m8I_VSkw91vRs;)Z$&~)UD89Fj|>$pC47*NB(>iZnAx#;W~m^W z<)m$vX^M%7qE1e;r2>jQ#0-VXfKusKkSGE=^56C6`s3bv?)RU2?>V3Exg|$K4;UMn z8$lotV`NBBxV{d4jP-{4+;W^=r!QaN!w>9-&_^uZ=$p040Y?HLkhZdo+LKTS#PAd{ zC?N7&ynL#SEW~Vup6EX`>W`#ufW?&s8B*etTCTY$OQi#I>78A@L6i<^pxfoCGbVz(u75=d6KwB9AhFRrb0-|HA-&Sp3!gj_r*@>TQ zIl^czBF&=ME%)0w4OBbo_(YZ=q6xE03D{aktJHszHEw~*zV2C`ro0GRqv>!hUQUwS zmd{AzB^vq6tD=LUkp(Cx+RH=cjMujHB zET{2VLHH0wW_yVpRz&r z;SNq)_=16qgxgNREb}8pM3j1`mnez5-Q7~V!4+INU`Y}dIuP!k$K&5P3^sN-Mwdst zFfvF!9B}=2o6)0RrhLENed}6tBLib-VextY!2eq|S>~j_4{V#n5+z?jo73q4Vic1!=>wJ@@b3|BgwT&n`C2| z7qyv;^hR#8@eG(fI&dfb-#s|kWu z=+^>oe5DloEZ!p5@MIOGUf?5Z>LktV>cSX0S#&Y(4XI60owjM8qc*JvMnEkQdtgYn zf$Dx|2XPef7JRVS?Hy_->7gF}-q)>BeHRkWj_n1xtVRID-?3qXRX@_iH@VSuaJy9P z7-vJt>9A~I%<9z^v2#jkQsfh}&qh*rvA%gi;=OTR#6(nose&&1Mg8vfq4cI3)up!`#eS!k)k zmlqRR!&;7`#i3PSc`sVl_x)V^B(GeuQ2|XuHy}V5Q5^96_-C`oI5i*p?aK~Ll$k z`3CA-bvkYre_t50r2?+H@=sqnijNyvDnKM%Mujm5bJZlANJANjPZH&b=S$bs`K6L6 z9vQNFo+&~&FvJ_;$l*`ANW-U1)nbg$9EAvTjmKkMM6Z$9a!q^O$Qi_KfTxk`9l2uKuPh1Ql;EZd&qDLI#Hh(f6M?|1WorE8_qF literal 0 HcmV?d00001 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 new file mode 100644 index 0000000000000000000000000000000000000000..0918b7fd511a807b03c40468527b049a248172d0 GIT binary patch literal 928 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VM%xNb!1@J z*w6hZk(Ggg*~`<#F{C2y?OoeGo&dpA`H+TBqo|&JE-Y8D~ZrASq>__)${f~;9j@?i5eel-B-zf2O z&9>Vo=cd%}&6|DtbJ4k~IUBT3*=<|C-?i+0b9MCRZx5ak8z}H@kI78`pVd!2uRYoO z<+RHA?QDu5?zHiXBotE~evZgw{efmG`Q}HJKou4fJe&k3^ z`fqm9_SC#wwYs+rqAXn6C;r*I5`D69L(_qJ2bw2`#zWihyzAHBQM<3^v@RsQZz#3+ Y!>exB`>J;H%|{?1Pgg&ebxsLQ00#PR6#xJL literal 0 HcmV?d00001 diff --git a/src/Gtk/Perspex.Cairo/CairoExtensions.cs b/src/Gtk/Perspex.Cairo/CairoExtensions.cs index e7c3951518..5798796a37 100644 --- a/src/Gtk/Perspex.Cairo/CairoExtensions.cs +++ b/src/Gtk/Perspex.Cairo/CairoExtensions.cs @@ -7,6 +7,11 @@ namespace Perspex.Cairo public static class CairoExtensions { + public static Cairo.Color ToCairo(this Perspex.Media.Color color) + { + return new Cairo.Color(color.R / 255.0, color.G / 255.0, color.B / 255.0, color.A / 255.0); + } + public static Cairo.Matrix ToCairo(this Matrix m) { return new Cairo.Matrix(m.M11, m.M12, m.M21, m.M22, m.M31, m.M32); diff --git a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs index 75aa9f924b..ce1dc5c796 100644 --- a/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs +++ b/src/Gtk/Perspex.Cairo/Media/DrawingContext.cs @@ -227,10 +227,14 @@ namespace Perspex.Cairo.Media } else if (linearGradientBrush != null) { - Cairo.LinearGradient g = new Cairo.LinearGradient(linearGradientBrush.StartPoint.X * destinationSize.Width, linearGradientBrush.StartPoint.Y * destinationSize.Height, linearGradientBrush.EndPoint.X * destinationSize.Width, linearGradientBrush.EndPoint.Y * destinationSize.Height); + Cairo.LinearGradient g = new Cairo.LinearGradient( + linearGradientBrush.StartPoint.X * destinationSize.Width, + linearGradientBrush.StartPoint.Y * destinationSize.Height, + linearGradientBrush.EndPoint.X * destinationSize.Width, + linearGradientBrush.EndPoint.Y * destinationSize.Height); foreach (var s in linearGradientBrush.GradientStops) - g.AddColorStop(s.Offset, new Cairo.Color(s.Color.R / 255.0, s.Color.G / 255.0, s.Color.B / 255.0, s.Color.A / 255.0)); + g.AddColorStop(s.Offset, s.Color.ToCairo()); g.Extend = Cairo.Extend.Pad; diff --git a/tests/Perspex.RenderTests/Media/LinearGradientBrushTests.cs b/tests/Perspex.RenderTests/Media/LinearGradientBrushTests.cs index e4d0fbde6f..2a309ee7f6 100644 --- a/tests/Perspex.RenderTests/Media/LinearGradientBrushTests.cs +++ b/tests/Perspex.RenderTests/Media/LinearGradientBrushTests.cs @@ -10,7 +10,11 @@ using System.Text; using System.Threading.Tasks; using Xunit; +#if PERSPEX_CAIRO +namespace Perspex.Cairo.RenderTests.Media +#else namespace Perspex.Direct2D1.RenderTests.Media +#endif { public class LinearGradientBrushTests : TestBase { diff --git a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs index 90b327cd66..5bff4198cb 100644 --- a/tests/Perspex.RenderTests/Media/VisualBrushTests.cs +++ b/tests/Perspex.RenderTests/Media/VisualBrushTests.cs @@ -7,7 +7,11 @@ using Perspex.Layout; using Perspex.Media; using Xunit; +#if PERSPEX_CAIRO +namespace Perspex.Cairo.RenderTests.Media +#else namespace Perspex.Direct2D1.RenderTests.Media +#endif { public class VisualBrushTests : TestBase { @@ -16,7 +20,11 @@ namespace Perspex.Direct2D1.RenderTests.Media { } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Align_TopLeft() { Decorator target = new Decorator @@ -55,7 +63,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Align_Center() { Decorator target = new Decorator @@ -94,7 +106,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Align_BottomRight() { Decorator target = new Decorator @@ -133,7 +149,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Stretch_Fill_Large() { Decorator target = new Decorator @@ -170,7 +190,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Stretch_Uniform() { Decorator target = new Decorator @@ -207,7 +231,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Stretch_UniformToFill() { Decorator target = new Decorator @@ -244,7 +272,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_SourceRect_Absolute() { Decorator target = new Decorator @@ -281,7 +313,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_DestinationRect_Absolute() { Decorator target = new Decorator @@ -318,7 +354,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_SourceRect_DestinationRect_Absolute() { Decorator target = new Decorator @@ -356,7 +396,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_SourceRect_DestinationRect_Percent() { Decorator target = new Decorator @@ -394,7 +438,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Tile() { Decorator target = new Decorator @@ -433,7 +481,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_Tile_Alignment_BottomRight() { Decorator target = new Decorator @@ -473,7 +525,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_FlipX() { Decorator target = new Decorator @@ -512,7 +568,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_FlipY() { Decorator target = new Decorator @@ -551,7 +611,11 @@ namespace Perspex.Direct2D1.RenderTests.Media CompareImages(); } +#if PERSPEX_CAIRO + [Fact(Skip = "VisualBrush not yet implemented on Cairo")] +#else [Fact] +#endif public void VisualBrush_FlipXY() { Decorator target = new Decorator diff --git a/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj b/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj index e28d91a6b4..024b77b93d 100644 --- a/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj +++ b/tests/Perspex.RenderTests/Perspex.Cairo.RenderTests.csproj @@ -74,6 +74,8 @@ + + From c10ac8e68d33ca08dcb8c4a61a8745e14c86a666 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 02:19:44 +0200 Subject: [PATCH 15/20] Added LinearGradient vertical fill tests. --- ...rush_RedBlue_Horizontal_Fill.expected.png} | Bin ...ntBrush_RedBlue_Vertical_Fill.expected.png | Bin 0 -> 653 bytes ...Brush_RedBlue_Horizontal_Fill.expected.png | Bin ...ntBrush_RedBlue_Vertical_Fill.expected.png | Bin 0 -> 1959 bytes .../Media/LinearGradientBrushTests.cs | 29 +++++++++++++++++- 5 files changed, 28 insertions(+), 1 deletion(-) rename Tests/TestFiles/Cairo/Media/LinearGradientBrush/{LinearGradientBrush_RedBlue_Fill.expected.png => LinearGradientBrush_RedBlue_Horizontal_Fill.expected.png} (100%) create mode 100644 Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Vertical_Fill.expected.png rename tests/TestFiles/Direct2D1/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png => Tests/TestFiles/Direct2D1/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Horizontal_Fill.expected.png (100%) create mode 100644 Tests/TestFiles/Direct2D1/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Vertical_Fill.expected.png diff --git a/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png b/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Horizontal_Fill.expected.png similarity index 100% rename from Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Fill.expected.png rename to Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Horizontal_Fill.expected.png diff --git a/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Vertical_Fill.expected.png b/Tests/TestFiles/Cairo/Media/LinearGradientBrush/LinearGradientBrush_RedBlue_Vertical_Fill.expected.png new file mode 100644 index 0000000000000000000000000000000000000000..d09c0c30b4c47e6c2c734bac6b5c4abce8db89b5 GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu_bxCyD z45^s&_L?JKlYb(JG=P51W+FkoZqrmZbtGM?KqZq8+6S+ z#Qi;(zE|-_;@`jVd?`{K{b>pXx5U-2z3%$nF#FBV)lCio0vudS2OShFHY#Xvu&_2R zP!Ql@X%gmcYH~0T;PBG{$~roNq?j8Y9BBf|im(tTh22a%)}cy~Y8|R0VO~Hr6UBFU iqzs0W$05n$0l#ef&wV$xuJOtO33$5txvXjqj#{W92IB`}i^QpZ`qe`&RMkD&O(r z_~SSn&Uk-6@oIQ7?9T^g@Vl5SQNd$O>}ua-oRTJ+ZusNs$Mtx z%HK6oDrn7n!IED}=VOfIiVHY6 zG$f^}0$o^Gwg_YRI~M}XjgwME=dVF|tO#l@ng>Epn8zeuc=whlbA8~isYvOOEGQ{a z&&8OWa@M_zlZ-0b%mbm~csq{*s0C<=O>iOru z<|-l;F?pO~Z8qE_arAC8*bG&rAtvI~c!16ONW9;*79dZhK%ABH!F#3iQjBT&RtQ4r z@oG_5%oz~s^_Yf+Ot=p@gPWrX+Myc;Z^XMa-0a35ASb~jCg}R^aDWzD>$%z5vn=c* z2|9a#wVCs|S~R2JDhSn`utG!J4qD6gkLwPRc*~zMXl+4@jPh8v3A%W70z*UQ`ocIK zH`hT9Wi-GLosMf&HwWM++jkT6okOq_!XpBqbyx+v;|usP^Nj(i3!?uh zO!m$+v{ke&kjJib5?FlJ<}|0eBD=*?ooTQdX`IqsKd!WB=O_npd7&yDr%~w@{*> zDk?Yn_h}uId)Tmt&i{r9mJYIEI{SCR{u(ZD$kM-=;us_?l{YHC@YUpzWDWL+FDqTLa8Bt%J~Ba+9qGG-CUFzeCpl?JZFTvh6u0KTvc+ zEQB$g>=dSrFmF#`$?-xqOqkgGW(v8DJJ_(n+=o03jKxx3XoT4$9?fBEoF2}4r$$Om zf^<%Cj%&-C@7_ z+1|^3bXi9MYDj=_&K?-EuoqTUm@!30nSaG@OP_ff62pB6i*dj4ClX&?Q4eePeuff> zv6%uV>V5-F;wjhQL>a^x>4>vj0gEwP0H;u}0)%!fO_5UO9b-WKsH+>saAw0Up1fI0 z;=Tec4v2sy+sI5FC9Q zngK%B2INQ#9t%RAK0_qFA-)}odsJ$<-8VfTr@xzzc5u4DaKeH4YLQ!i5#%5}wrI#w z3=U61MiaokDuDZYtkHZs6olsGts&?nG6WU|ano_TYtvvHSXmrF-ykCa+Pi7E;mr*I zvo67j+DX7obvg5yTJ&u5_aO9H7!S>#cM&deiLO^IYQOX&IErc4aeq$lgq)4%RuZ(K z3Ql1Javk9QX#jscvxA`5SFuB|cdzG$-wFWlg<)`0Ijo1vA|WkHEs{LF0_v?jmT10f zA=oTF>qF4fNw_SG(@#Q Date: Tue, 15 Sep 2015 15:03:54 +0500 Subject: [PATCH 16/20] consistent names for xaml type converters --- .../Perspex.Markup.Xaml/Context/PerspexWiringContext.cs | 6 +++--- .../{BitmapConverter.cs => BitmapTypeConverter.cs} | 2 +- .../Converters/{BrushConverter.cs => BrushTypeConverter.cs} | 2 +- .../{ThicknessConverter.cs => ThicknessTypeConverter.cs} | 2 +- src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) rename src/Markup/Perspex.Markup.Xaml/Converters/{BitmapConverter.cs => BitmapTypeConverter.cs} (94%) rename src/Markup/Perspex.Markup.Xaml/Converters/{BrushConverter.cs => BrushTypeConverter.cs} (94%) rename src/Markup/Perspex.Markup.Xaml/Converters/{ThicknessConverter.cs => ThicknessTypeConverter.cs} (94%) diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs index 7ab5758f41..7fa4822da3 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs @@ -80,12 +80,12 @@ namespace Perspex.Markup.Xaml.Context var typeConverterProvider = new TypeConverterProvider(); var converters = new[] { - new TypeConverterRegistration(typeof(Bitmap), new BitmapConverter()), - new TypeConverterRegistration(typeof(Brush), new BrushConverter()), + new TypeConverterRegistration(typeof(Bitmap), new BitmapTypeConverter()), + new TypeConverterRegistration(typeof(Brush), new BrushTypeConverter()), new TypeConverterRegistration(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()), new TypeConverterRegistration(typeof(GridLength), new GridLengthTypeConverter()), new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()), - new TypeConverterRegistration(typeof(Thickness), new ThicknessConverter()), + new TypeConverterRegistration(typeof(Thickness), new ThicknessTypeConverter()), }; typeConverterProvider.AddAll(converters); diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/BitmapTypeConverter.cs similarity index 94% rename from src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs rename to src/Markup/Perspex.Markup.Xaml/Converters/BitmapTypeConverter.cs index 392da12630..1aa1660079 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/BitmapConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/BitmapTypeConverter.cs @@ -8,7 +8,7 @@ using Perspex.Media.Imaging; namespace Perspex.Markup.Xaml.Converters { - public class BitmapConverter : ITypeConverter + public class BitmapTypeConverter : ITypeConverter { public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/BrushTypeConverter.cs similarity index 94% rename from src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs rename to src/Markup/Perspex.Markup.Xaml/Converters/BrushTypeConverter.cs index d734caf37a..197cb20a8d 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/BrushConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/BrushTypeConverter.cs @@ -8,7 +8,7 @@ using Perspex.Media; namespace Perspex.Markup.Xaml.Converters { - public class BrushConverter : ITypeConverter + public class BrushTypeConverter : ITypeConverter { public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { diff --git a/src/Markup/Perspex.Markup.Xaml/Converters/ThicknessConverter.cs b/src/Markup/Perspex.Markup.Xaml/Converters/ThicknessTypeConverter.cs similarity index 94% rename from src/Markup/Perspex.Markup.Xaml/Converters/ThicknessConverter.cs rename to src/Markup/Perspex.Markup.Xaml/Converters/ThicknessTypeConverter.cs index a001913711..1e33525494 100644 --- a/src/Markup/Perspex.Markup.Xaml/Converters/ThicknessConverter.cs +++ b/src/Markup/Perspex.Markup.Xaml/Converters/ThicknessTypeConverter.cs @@ -7,7 +7,7 @@ using OmniXaml.TypeConversion; namespace Perspex.Markup.Xaml.Converters { - public class ThicknessConverter : ITypeConverter + public class ThicknessTypeConverter : ITypeConverter { public bool CanConvertFrom(IXamlTypeConverterContext context, Type sourceType) { diff --git a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj index e146cac468..d2aaa43766 100644 --- a/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj +++ b/src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj @@ -40,11 +40,11 @@ - + - - + + From 31fff6f706cf3de7fc5d84cbce6b693bfd2e773a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 15 Sep 2015 12:25:02 +0200 Subject: [PATCH 17/20] Update build.md --- docs/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build.md b/docs/build.md index d62f285f89..4a25794ac5 100644 --- a/docs/build.md +++ b/docs/build.md @@ -6,7 +6,7 @@ Perspex requires Visual Studio 2015 to build on Windows. ### Install GTK Sharp -To compile the full project under windows, you must have gtk-sharp installed. However, if you're +To compile the full project under windows, you must have [gtk-sharp](http://www.mono-project.com/download/#download-win) installed. However, if you're not interested in building the cross-platform bits you can simply unload the Perspex.Cairo and Perspex.Gtk project in Visual Studio. From 8564a74fc1b4eb6d5877167ee25b21c1d791c2cd Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 15 Sep 2015 18:57:22 +0300 Subject: [PATCH 18/20] Changed default namespace --- samples/XamlTestApplication/Views/MainWindow.xaml | 2 +- src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/XamlTestApplication/Views/MainWindow.xaml b/samples/XamlTestApplication/Views/MainWindow.xaml index da27d04242..96f4db9653 100644 --- a/samples/XamlTestApplication/Views/MainWindow.xaml +++ b/samples/XamlTestApplication/Views/MainWindow.xaml @@ -1,5 +1,5 @@  diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs index 7fa4822da3..45894a58eb 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs @@ -22,7 +22,7 @@ namespace Perspex.Markup.Xaml.Context public class PerspexWiringContext : IWiringContext { private readonly WiringContext _context; - private const string PerspexNs = "https://github.com/grokys/Perspex"; + private const string PerspexNs = "https://github.com/perspex"; public PerspexWiringContext(ITypeFactory typeFactory) { From afd25d7b98dc4af60710c848479701104a85d00a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 15 Sep 2015 18:59:27 +0300 Subject: [PATCH 19/20] Try to load .paml if .xaml wasn't found --- .../Perspex.Markup.Xaml/PerspexXamlLoader.cs | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs b/src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs index a2e7cfbabe..cf8409d5e9 100644 --- a/src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs +++ b/src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs @@ -2,6 +2,8 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using System.Collections.Generic; +using System.IO; using System.Reflection; using OmniXaml; using Perspex.Markup.Xaml.Context; @@ -52,7 +54,27 @@ namespace Perspex.Markup.Xaml /// The loaded object. public object Load(Type type, object rootInstance = null) { - return Load(GetUriFor(type), rootInstance); + var assetLocator = Locator.Current.GetService(); + if (assetLocator == null) + { + throw new InvalidOperationException( + "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); + } + foreach (var uri in GetUrisFor(type)) + { + Stream stream; + try + { + stream= assetLocator.Open(uri); + } + catch (FileNotFoundException) + { + continue; + } + using (stream) + return Load(stream, rootInstance); + } + throw new FileNotFoundException("Unable to find view for " + type.FullName); } /// @@ -84,7 +106,7 @@ namespace Perspex.Markup.Xaml /// /// The type. /// The URI. - private static Uri GetUriFor(Type type) + private static IEnumerable GetUrisFor(Type type) { if (type.Namespace != null) { @@ -97,10 +119,9 @@ namespace Perspex.Markup.Xaml replace = replace + "/"; } - return new Uri(replace + type.Name + ".xaml", UriKind.Relative); + foreach (var ext in new[] {".xaml", ".paml"}) + yield return new Uri(replace + type.Name + ext, UriKind.Relative); } - - return null; } } } From bec230211a0f08038bcca73d5661c80dd4a9e51a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Tue, 15 Sep 2015 22:45:27 +0300 Subject: [PATCH 20/20] Now resolving xml namespaces via attributes --- Perspex.sln | 1 + .../XamlTestApplication/Views/MainWindow.xaml | 112 +----------------- src/Gtk/Perspex.Gtk/GtkPlatform.cs | 1 + src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj | 3 + .../Context/PerspexWiringContext.cs | 53 ++++----- .../Properties/AssemblyInfo.cs | 3 + .../Metadata/XmlnsDefinitionAttribute.cs | 21 ++++ src/Perspex.Base/Perspex.Base.csproj | 2 + .../Platform/IPclPlatformWrapper.cs | 14 +++ .../Properties/AssemblyInfo.cs | 6 +- .../Properties/AssemblyInfo.cs | 2 + src/Shared/PclPlatformWrapper.cs | Bin 0 -> 806 bytes .../Perspex.Win32/Perspex.Win32.csproj | 3 + src/Windows/Perspex.Win32/Win32Platform.cs | 1 + 14 files changed, 85 insertions(+), 137 deletions(-) create mode 100644 src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs create mode 100644 src/Perspex.Base/Platform/IPclPlatformWrapper.cs create mode 100644 src/Shared/PclPlatformWrapper.cs diff --git a/Perspex.sln b/Perspex.sln index 54c810f636..20a7fa624e 100644 --- a/Perspex.sln +++ b/Perspex.sln @@ -79,6 +79,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DEF5-D50F-4975-8B72-124C9EB54066}" ProjectSection(SolutionItems) = preProject + src\Shared\PclPlatformWrapper.cs = src\Shared\PclPlatformWrapper.cs src\Shared\SharedAssemblyInfo.cs = src\Shared\SharedAssemblyInfo.cs EndProjectSection EndProject diff --git a/samples/XamlTestApplication/Views/MainWindow.xaml b/samples/XamlTestApplication/Views/MainWindow.xaml index 96f4db9653..78d30bda9f 100644 --- a/samples/XamlTestApplication/Views/MainWindow.xaml +++ b/samples/XamlTestApplication/Views/MainWindow.xaml @@ -2,111 +2,9 @@ xmlns="https://github.com/perspex" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Perspex Test Application" Height="350" Width="525"> - - - - - - - - - + + + \ No newline at end of file diff --git a/src/Gtk/Perspex.Gtk/GtkPlatform.cs b/src/Gtk/Perspex.Gtk/GtkPlatform.cs index d02e112845..2881bd292f 100644 --- a/src/Gtk/Perspex.Gtk/GtkPlatform.cs +++ b/src/Gtk/Perspex.Gtk/GtkPlatform.cs @@ -28,6 +28,7 @@ namespace Perspex.Gtk public static void Initialize() { var locator = Locator.CurrentMutable; + locator.Register(() => new PclPlatformWrapper(), typeof(IPclPlatformWrapper)); locator.Register(() => new WindowImpl(), typeof(IWindowImpl)); locator.Register(() => new PopupImpl(), typeof(IPopupImpl)); locator.Register(() => new ClipboardImpl(), typeof(IClipboard)); diff --git a/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj b/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj index 563d87b2a3..95d3c8c5c5 100644 --- a/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj +++ b/src/Gtk/Perspex.Gtk/Perspex.Gtk.csproj @@ -58,6 +58,9 @@ + + PclPlatformWrapper.cs + diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs index 45894a58eb..cf16bcb8f7 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs +++ b/src/Markup/Perspex.Markup.Xaml/Context/PerspexWiringContext.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Linq; using System.Reflection; using Glass; using OmniXaml; @@ -16,6 +17,10 @@ using Perspex.Markup.Xaml.DataBinding; using Perspex.Markup.Xaml.MarkupExtensions; using Perspex.Media; using Perspex.Media.Imaging; +using Perspex.Metadata; +using Perspex.Platform; +using Perspex.Styling; +using Splat; namespace Perspex.Markup.Xaml.Context { @@ -39,37 +44,27 @@ namespace Perspex.Markup.Xaml.Context { var xamlNamespaceRegistry = new XamlNamespaceRegistry(); - var rootType = typeof(Control); - var bindingType = typeof(BindingExtension); - var templateType = typeof(XamlDataTemplate); - - var definitionForRoot = XamlNamespace - .Map(PerspexNs) - .With( - new[] - { - Route.Assembly(rootType.GetTypeInfo().Assembly).WithNamespaces( - new[] - { - rootType.Namespace - }), - Route.Assembly(bindingType.GetTypeInfo().Assembly).WithNamespaces( - new[] - { - bindingType.Namespace, - }), - Route.Assembly(templateType.GetTypeInfo().Assembly).WithNamespaces( - new[] - { - templateType.Namespace, - }) - }); - - foreach (var ns in new List { definitionForRoot }) + var forcedAssemblies = new[] { - xamlNamespaceRegistry.AddNamespace(ns); + typeof (Control), + typeof(Style) + }.Select(t => t.GetTypeInfo().Assembly); + + foreach (var nsa in + forcedAssemblies + .Concat(Locator.Current.GetService().GetLoadedAssemblies()) + .Distinct() + .SelectMany(asm + => asm.GetCustomAttributes().Select(attr => new {asm, attr})) + .GroupBy(entry => entry.attr.XmlNamespace)) + { + var def = XamlNamespace.Map(nsa.Key) + .With(nsa.GroupBy(x => x.asm).Select( + a => Route.Assembly(a.Key) + .WithNamespaces(a.Select(entry => entry.attr.ClrNamespace).ToList()) + )); + xamlNamespaceRegistry.AddNamespace(def); } - xamlNamespaceRegistry.RegisterPrefix(new PrefixRegistration(string.Empty, PerspexNs)); return xamlNamespaceRegistry; diff --git a/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs b/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs index eea5e0803d..07a61a6798 100644 --- a/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs +++ b/src/Markup/Perspex.Markup.Xaml/Properties/AssemblyInfo.cs @@ -2,5 +2,8 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Reflection; +using Perspex.Metadata; [assembly: AssemblyTitle("Perspex.Markup.Xaml")] +[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Markup.Xaml.MarkupExtensions")] +[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Markup.Xaml.Templates")] \ No newline at end of file diff --git a/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs b/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs new file mode 100644 index 0000000000..63371bf80f --- /dev/null +++ b/src/Perspex.Base/Metadata/XmlnsDefinitionAttribute.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Perspex.Metadata +{ + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] + public class XmlnsDefinitionAttribute : Attribute + { + public string XmlNamespace { get; set; } + public string ClrNamespace { get; set; } + + public XmlnsDefinitionAttribute(string xmlNamespace, string clrNamespace) + { + XmlNamespace = xmlNamespace; + ClrNamespace = clrNamespace; + } + } +} diff --git a/src/Perspex.Base/Perspex.Base.csproj b/src/Perspex.Base/Perspex.Base.csproj index 8370b131f1..0ab51860f1 100644 --- a/src/Perspex.Base/Perspex.Base.csproj +++ b/src/Perspex.Base/Perspex.Base.csproj @@ -46,8 +46,10 @@ + + diff --git a/src/Perspex.Base/Platform/IPclPlatformWrapper.cs b/src/Perspex.Base/Platform/IPclPlatformWrapper.cs new file mode 100644 index 0000000000..c57b87a738 --- /dev/null +++ b/src/Perspex.Base/Platform/IPclPlatformWrapper.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace Perspex.Platform +{ + public interface IPclPlatformWrapper + { + Assembly[] GetLoadedAssemblies(); + } +} diff --git a/src/Perspex.Controls/Properties/AssemblyInfo.cs b/src/Perspex.Controls/Properties/AssemblyInfo.cs index 479c2fc91b..4cda6c4aa5 100644 --- a/src/Perspex.Controls/Properties/AssemblyInfo.cs +++ b/src/Perspex.Controls/Properties/AssemblyInfo.cs @@ -3,6 +3,10 @@ using System.Reflection; using System.Runtime.CompilerServices; +using Perspex.Metadata; [assembly: AssemblyTitle("Perspex.Controls")] -[assembly: InternalsVisibleTo("Perspex.Controls.UnitTests")] \ No newline at end of file +[assembly: InternalsVisibleTo("Perspex.Controls.UnitTests")] + +[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Controls")] +[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Controls.Primitives")] \ No newline at end of file diff --git a/src/Perspex.Styling/Properties/AssemblyInfo.cs b/src/Perspex.Styling/Properties/AssemblyInfo.cs index 3dbe71ef35..f06c17710e 100644 --- a/src/Perspex.Styling/Properties/AssemblyInfo.cs +++ b/src/Perspex.Styling/Properties/AssemblyInfo.cs @@ -2,5 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Reflection; +using Perspex.Metadata; [assembly: AssemblyTitle("Perspex.Styling")] +[assembly: XmlnsDefinition("https://github.com/perspex", "Perspex.Styling")] \ No newline at end of file diff --git a/src/Shared/PclPlatformWrapper.cs b/src/Shared/PclPlatformWrapper.cs new file mode 100644 index 0000000000000000000000000000000000000000..9057a8085b2359748b34cc3ad0663ae476b75ecc GIT binary patch literal 806 zcma))K}*9x6olt2_#gJDm-MbEh=LRp#0nn7Lru~eY15K4ViEtk`pu@2wpb`jv)#Az zX6EgCKi@s|6m+SX=31&!p|M`IAay1+iJ|S|U2`j9z z)bW&)<=l6^8OTE&plaP4^irZ_L}Wx7{$~*#U~QFe)yGAEdmU}X0Z4o6Zp@Zw3P;cg z{3PBNuy%ZNymZd(cgAwfBlarp4VkW`V|EPz#&U(4YDi8&M!BlVbv0CC%oyx|7p=kM z_&JSL@48KN4{8+M`ZZhDeR68_8$7%2`X80et|fGF5`DLo{`s==G~U#(xYs^yV;|8O z(tl5YU+IKje=n^0KjRAoa=hlaenG<>_2gLB@8sB0PkJVLO=Q80%uw}AWLvm`Sk0Vz kO3!p2dF<|r40p$UNSJNEPX)GwZS$^G*i`RW+xP#{FKM2P{{R30 literal 0 HcmV?d00001 diff --git a/src/Windows/Perspex.Win32/Perspex.Win32.csproj b/src/Windows/Perspex.Win32/Perspex.Win32.csproj index a55bba662b..68093baf10 100644 --- a/src/Windows/Perspex.Win32/Perspex.Win32.csproj +++ b/src/Windows/Perspex.Win32/Perspex.Win32.csproj @@ -62,6 +62,9 @@ + + PclPlatformWrapper.cs + Properties\SharedAssemblyInfo.cs diff --git a/src/Windows/Perspex.Win32/Win32Platform.cs b/src/Windows/Perspex.Win32/Win32Platform.cs index da4be6b6a6..4cfe797450 100644 --- a/src/Windows/Perspex.Win32/Win32Platform.cs +++ b/src/Windows/Perspex.Win32/Win32Platform.cs @@ -40,6 +40,7 @@ namespace Perspex.Win32 private static void InitializeInternal() { var locator = Locator.CurrentMutable; + locator.Register(()=>new PclPlatformWrapper(), typeof(IPclPlatformWrapper)); locator.Register(() => new PopupImpl(), typeof(IPopupImpl)); locator.Register(() => new ClipboardImpl(), typeof(IClipboard)); locator.Register(() => WindowsKeyboardDevice.Instance, typeof(IKeyboardDevice));