diff --git a/Cairo/Perspex.Cairo/CairoPlatform.cs b/Cairo/Perspex.Cairo/CairoPlatform.cs new file mode 100644 index 0000000000..9802767489 --- /dev/null +++ b/Cairo/Perspex.Cairo/CairoPlatform.cs @@ -0,0 +1,67 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Cairo +{ + using System; + using global::Cairo; + using Perspex.Cairo.Media; + using Perspex.Cairo.Media.Imaging; + using Perspex.Platform; + using Perspex.Threading; + using Splat; + + public class CairoPlatform : IPlatformRenderInterface + { + private static CairoPlatform instance = new CairoPlatform(); + + private static TextService textService = new TextService(); + + public static void Initialize() + { + var locator = Locator.CurrentMutable; + locator.Register(() => instance, typeof(IPlatformRenderInterface)); + locator.Register(() => textService, typeof(ITextService)); + //locator.Register(() => d2d1Factory, typeof(SharpDX.Direct2D1.Factory)); + //locator.Register(() => dwFactory, typeof(SharpDX.DirectWrite.Factory)); + //locator.Register(() => imagingFactory, typeof(SharpDX.WIC.ImagingFactory)); + } + + public ITextService TextService + { + get { /*return textService;*/ throw new NotImplementedException(); } + } + + public IBitmapImpl CreateBitmap(int width, int height) + { + throw new NotImplementedException(); + //return new BitmapImpl(imagingFactory, width, height); + } + + public IRenderer CreateRenderer(IntPtr handle, double width, double height) + { + return new Renderer(handle, width, height); + } + + public IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height) + { + throw new NotImplementedException(); + //return new RenderTargetBitmapImpl(imagingFactory, d2d1Factory, width, height); + } + + public IStreamGeometryImpl CreateStreamGeometry() + { + throw new NotImplementedException(); + //return new StreamGeometryImpl(); + } + + public IBitmapImpl LoadBitmap(string fileName) + { + ImageSurface result = new ImageSurface(fileName); + return new BitmapImpl(result); + } + } +} diff --git a/Cairo/Perspex.Cairo/Media/DrawingContext.cs b/Cairo/Perspex.Cairo/Media/DrawingContext.cs new file mode 100644 index 0000000000..8db1fa3ca2 --- /dev/null +++ b/Cairo/Perspex.Cairo/Media/DrawingContext.cs @@ -0,0 +1,151 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2013 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Cairo.Media +{ + using System; + using System.Reactive.Disposables; + using global::Cairo; + using Perspex.Media; + using IBitmap = Perspex.Media.Imaging.IBitmap; + using Matrix = Perspex.Matrix; + + /// + /// Draws using Direct2D1. + /// + public class DrawingContext : IDrawingContext, IDisposable + { + /// + /// The cairo context. + /// + private Context context; + + /// + /// Initializes a new instance of the class. + /// + /// The target surface. + public DrawingContext(Surface surface) + { + this.context = new Context(surface); + } + + public Matrix CurrentTransform + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + /// + /// Ends a draw operation. + /// + public void Dispose() + { + this.context.Dispose(); + } + + public void DrawImage(IBitmap bitmap, double opacity, Rect sourceRect, Rect destRect) + { + throw new NotImplementedException(); + } + + /// + /// Draws a line. + /// + /// The stroke pen. + /// The first point of the line. + /// The second point of the line. + public void DrawLine(Pen pen, Perspex.Point p1, Perspex.Point p2) + { + throw new NotImplementedException(); + } + + /// + /// Draws a geometry. + /// + /// The fill brush. + /// The stroke pen. + /// The geometry. + public void DrawGeometry(Perspex.Media.Brush brush, Perspex.Media.Pen pen, Perspex.Media.Geometry geometry) + { + throw new NotImplementedException(); + } + + /// + /// Draws the outline of a rectangle. + /// + /// The pen. + /// The rectangle bounds. + public void DrawRectange(Pen pen, Rect rect) + { + this.SetPen(pen); + this.context.Rectangle(rect.X, rect.Y, rect.Width, rect.Height); + this.context.Stroke(); + } + + /// + /// Draws text. + /// + /// The foreground brush. + /// The output rectangle. + /// The text. + public void DrawText(Perspex.Media.Brush foreground, Rect rect, FormattedText text) + { + // TODO: Implement + } + + /// + /// Draws a filled rectangle. + /// + /// The brush. + /// The rectangle bounds. + public void FillRectange(Perspex.Media.Brush brush, Rect rect) + { + this.SetBrush(brush); + this.context.Rectangle(rect.X, rect.Y, rect.Width, rect.Height); + this.context.Fill(); + } + + /// + /// Pushes a clip rectange. + /// + /// The clip rectangle. + /// A disposable used to undo the clip rectangle. + public IDisposable PushClip(Rect clip) + { + return Disposable.Empty; + } + + /// + /// Pushes a matrix transformation. + /// + /// The matrix + /// A disposable used to undo the transformation. + public IDisposable PushTransform(Matrix matrix) + { + return Disposable.Empty; + } + + private void SetBrush(Brush brush) + { + var solid = brush as SolidColorBrush; + + if (solid != null) + { + this.context.SetSourceRGBA( + solid.Color.R / 255.0, + solid.Color.G / 255.0, + solid.Color.B / 255.0, + solid.Color.A / 255.0); + } + } + + private void SetPen(Pen pen) + { + this.SetBrush(pen.Brush); + this.context.LineWidth = pen.Thickness; + } + } +} diff --git a/Cairo/Perspex.Cairo/Media/Imaging/BitmapImpl.cs b/Cairo/Perspex.Cairo/Media/Imaging/BitmapImpl.cs new file mode 100644 index 0000000000..6868002794 --- /dev/null +++ b/Cairo/Perspex.Cairo/Media/Imaging/BitmapImpl.cs @@ -0,0 +1,37 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Cairo.Media.Imaging +{ + using System; + using global::Cairo; + using Perspex.Platform; + + public class BitmapImpl : IBitmapImpl + { + private ImageSurface surface; + + public BitmapImpl(ImageSurface surface) + { + this.surface = surface; + } + + public int PixelWidth + { + get { return this.surface.Width; } + } + + public int PixelHeight + { + get { return this.surface.Height; } + } + + public void Save(string fileName) + { + throw new NotImplementedException(); + } + } +} diff --git a/Cairo/Perspex.Cairo/Media/TextService.cs b/Cairo/Perspex.Cairo/Media/TextService.cs new file mode 100644 index 0000000000..9a0be6bf53 --- /dev/null +++ b/Cairo/Perspex.Cairo/Media/TextService.cs @@ -0,0 +1,40 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Cairo.Media +{ + using System; + using System.Linq; + using Perspex.Media; + using Perspex.Platform; + + public class TextService : ITextService + { + public TextService() + { + } + + public int GetCaretIndex(FormattedText text, Point point, Size constraint) + { + throw new NotImplementedException(); + } + + public Point GetCaretPosition(FormattedText text, int caretIndex, Size constraint) + { + throw new NotImplementedException(); + } + + public double[] GetLineHeights(FormattedText text, Size constraint) + { + throw new NotImplementedException(); + } + + public Size Measure(FormattedText text, Size constraint) + { + return new Size(100, 30); + } + } +} diff --git a/Cairo/Perspex.Cairo/Perspex.Cairo.csproj b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj new file mode 100644 index 0000000000..4c3e1085e1 --- /dev/null +++ b/Cairo/Perspex.Cairo/Perspex.Cairo.csproj @@ -0,0 +1,110 @@ + + + + + Debug + AnyCPU + {FB05AC90-89BA-4F2F-A924-F37875FB547C} + Library + Properties + Perspex.Cairo + Perspex.Cairo + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\Dependencies\Mono.Cairo.dll + + + ..\..\packages\Splat.1.5.1\lib\Net45\Splat.dll + + + + + False + ..\..\packages\Rx-Core.2.2.5\lib\net45\System.Reactive.Core.dll + + + False + ..\..\packages\Rx-Interfaces.2.2.5\lib\net45\System.Reactive.Interfaces.dll + + + + + + + + + + + + + + + + + + {b09b78d8-9b26-48b0-9149-d64a2f120f3f} + Perspex.Base + + + {eb582467-6abb-43a1-b052-e981ba910e3a} + Perspex.SceneGraph + + + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + \ No newline at end of file diff --git a/Cairo/Perspex.Cairo/Properties/AssemblyInfo.cs b/Cairo/Perspex.Cairo/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..c143e5e311 --- /dev/null +++ b/Cairo/Perspex.Cairo/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Perspex.Cairo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Perspex.Cairo")] +[assembly: AssemblyCopyright("Copyright © 2014")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f999ba8b-64e7-40cc-98a4-003f1852d2a3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Cairo/Perspex.Cairo/Renderer.cs b/Cairo/Perspex.Cairo/Renderer.cs new file mode 100644 index 0000000000..b33e26b9c4 --- /dev/null +++ b/Cairo/Perspex.Cairo/Renderer.cs @@ -0,0 +1,104 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2013 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Cairo +{ + using System; + using Perspex.Platform; + using Splat; + using global::Cairo; + using System.Runtime.InteropServices; + using Perspex.Cairo.Media; + using Matrix = Perspex.Matrix; + + public class Renderer : IRenderer + { + /// + /// The target cairo surface. + /// + private Surface surface; + + /// + /// Initializes a new instance of the class. + /// + /// The window handle. + /// The width of the window. + /// The height of the window. + public Renderer(IntPtr hwnd, double width, double height) + { + surface = new Win32Surface(GetDC(hwnd)); + } + + /// + /// Initializes a new instance of the class. + /// + /// The target surface. + public Renderer(Surface surface) + { + this.surface = surface; + } + + /// + /// Renders the specified visual. + /// + /// The visual to render. + public void Render(IVisual visual) + { + using (DrawingContext context = new DrawingContext(this.surface)) + { + this.Render(visual, context); + } + } + + /// + /// Resizes the renderer. + /// + /// The new width. + /// The new height. + public void Resize(int width, int height) + { + var s = this.surface.CreateSimilar(Content.ColorAlpha, width, height); + this.surface.Dispose(); + this.surface = s; + } + + [DllImport("user32.dll")] + private static extern IntPtr GetDC(IntPtr hWnd); + + /// + /// Renders the specified visual. + /// + /// The visual to render. + /// The drawing context. + private void Render(IVisual visual, DrawingContext context) + { + if (visual.IsVisible && visual.Opacity > 0) + { + Matrix transform = Matrix.Identity; + + if (visual.RenderTransform != null) + { + Matrix current = context.CurrentTransform; + Matrix offset = Matrix.Translation(visual.TransformOrigin.ToPixels(visual.Bounds.Size)); + transform = -current * -offset * visual.RenderTransform.Value * offset * current; + } + + transform *= Matrix.Translation(visual.Bounds.Position); + + using (context.PushClip(visual.Bounds)) + using (context.PushTransform(transform)) + { + visual.Render(context); + + foreach (var child in visual.VisualChildren) + { + this.Render(child, context); + } + } + } + } + } +} diff --git a/Cairo/Perspex.Cairo/libcairo-2.dll b/Cairo/Perspex.Cairo/libcairo-2.dll new file mode 100644 index 0000000000..85c07db4b5 Binary files /dev/null and b/Cairo/Perspex.Cairo/libcairo-2.dll differ diff --git a/Cairo/Perspex.Cairo/libfontconfig-1.dll b/Cairo/Perspex.Cairo/libfontconfig-1.dll new file mode 100644 index 0000000000..92f55d86b8 Binary files /dev/null and b/Cairo/Perspex.Cairo/libfontconfig-1.dll differ diff --git a/Cairo/Perspex.Cairo/libfreetype-6.dll b/Cairo/Perspex.Cairo/libfreetype-6.dll new file mode 100644 index 0000000000..62a6cb661a Binary files /dev/null and b/Cairo/Perspex.Cairo/libfreetype-6.dll differ diff --git a/Cairo/Perspex.Cairo/libiconv-2.dll b/Cairo/Perspex.Cairo/libiconv-2.dll new file mode 100644 index 0000000000..4f72699007 Binary files /dev/null and b/Cairo/Perspex.Cairo/libiconv-2.dll differ diff --git a/Cairo/Perspex.Cairo/liblzma-5.dll b/Cairo/Perspex.Cairo/liblzma-5.dll new file mode 100644 index 0000000000..6d9ca19391 Binary files /dev/null and b/Cairo/Perspex.Cairo/liblzma-5.dll differ diff --git a/Cairo/Perspex.Cairo/libpixman-1-0.dll b/Cairo/Perspex.Cairo/libpixman-1-0.dll new file mode 100644 index 0000000000..589dbdb1e9 Binary files /dev/null and b/Cairo/Perspex.Cairo/libpixman-1-0.dll differ diff --git a/Cairo/Perspex.Cairo/libpng15-15.dll b/Cairo/Perspex.Cairo/libpng15-15.dll new file mode 100644 index 0000000000..1a84617b79 Binary files /dev/null and b/Cairo/Perspex.Cairo/libpng15-15.dll differ diff --git a/Cairo/Perspex.Cairo/libxml2-2.dll b/Cairo/Perspex.Cairo/libxml2-2.dll new file mode 100644 index 0000000000..e18b635ec1 Binary files /dev/null and b/Cairo/Perspex.Cairo/libxml2-2.dll differ diff --git a/Cairo/Perspex.Cairo/packages.config b/Cairo/Perspex.Cairo/packages.config new file mode 100644 index 0000000000..0ab7b56b8d --- /dev/null +++ b/Cairo/Perspex.Cairo/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Dependencies/Mono.Cairo.dll b/Dependencies/Mono.Cairo.dll new file mode 100644 index 0000000000..9b3b046cde Binary files /dev/null and b/Dependencies/Mono.Cairo.dll differ diff --git a/Perspex.sln b/Perspex.sln index b26d59b654..2e9becd51f 100644 --- a/Perspex.sln +++ b/Perspex.sln @@ -1,9 +1,9 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30723.0 +VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Windows", "Windows\Perspex.Win32\Perspex.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Win32", "Windows\Perspex.Win32\Perspex.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestApplication", "TestApplication\TestApplication.csproj", "{E3A1060B-50D0-44E8-88B6-F44EF2E5BD72}" EndProject @@ -41,6 +41,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Application", "Pers EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Diagnostics", "Perspex.Diagnostics\Perspex.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cairo", "Cairo", "{1D577B69-F23B-4C4F-8605-97704DAC75A9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Perspex.Cairo", "Cairo\Perspex.Cairo\Perspex.Cairo.csproj", "{FB05AC90-89BA-4F2F-A924-F37875FB547C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -119,6 +123,10 @@ Global {7062AE20-5DCC-4442-9645-8195BDECE63E}.Debug|Any CPU.Build.0 = Debug|Any CPU {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.ActiveCfg = Release|Any CPU {7062AE20-5DCC-4442-9645-8195BDECE63E}.Release|Any CPU.Build.0 = Release|Any CPU + {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB05AC90-89BA-4F2F-A924-F37875FB547C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -128,5 +136,6 @@ Global {E3A1060B-50D0-44E8-88B6-F44EF2E5BD72} = {B39A8919-9F95-48FE-AD7B-76E08B509888} {3E908F67-5543-4879-A1DC-08EACE79B3CD} = {B39A8919-9F95-48FE-AD7B-76E08B509888} {DABFD304-D6A4-4752-8123-C2CCF7AC7831} = {B39A8919-9F95-48FE-AD7B-76E08B509888} + {FB05AC90-89BA-4F2F-A924-F37875FB547C} = {1D577B69-F23B-4C4F-8605-97704DAC75A9} EndGlobalSection EndGlobal diff --git a/TestApplication/App.cs b/TestApplication/App.cs index f9357754a0..329dcdc8bb 100644 --- a/TestApplication/App.cs +++ b/TestApplication/App.cs @@ -1,6 +1,7 @@ namespace TestApplication { using Perspex; + using Perspex.Cairo; using Perspex.Direct2D1; using Perspex.Themes.Default; using Perspex.Win32; @@ -11,7 +12,11 @@ : base(new DefaultTheme()) { this.RegisterServices(); +#if PERSPEX_CAIRO + CairoPlatform.Initialize(); +#else Direct2D1Platform.Initialize(); +#endif Win32Platform.Initialize(); } } diff --git a/TestApplication/TestApplication.csproj b/TestApplication/TestApplication.csproj index 1726e900fc..493c1088ed 100644 --- a/TestApplication/TestApplication.csproj +++ b/TestApplication/TestApplication.csproj @@ -19,9 +19,10 @@ full false bin\Debug\ - DEBUG;TRACE + TRACE;DEBUG;PERSPEX_CAIRO prompt 4 + false AnyCPU @@ -96,6 +97,10 @@ + + {fb05ac90-89ba-4f2f-a924-f37875fb547c} + Perspex.Cairo + {799a7bb5-3c2c-48b6-85a7-406a12c420da} Perspex.Application @@ -142,7 +147,7 @@ {811a76cf-1cf6-440f-963b-bbe31bd72a82} - Perspex.Windows + Perspex.Win32 diff --git a/Windows/Perspex.Direct2D1/Direct2D1Platform.cs b/Windows/Perspex.Direct2D1/Direct2D1Platform.cs index f748c48a6b..e89e721207 100644 --- a/Windows/Perspex.Direct2D1/Direct2D1Platform.cs +++ b/Windows/Perspex.Direct2D1/Direct2D1Platform.cs @@ -1,5 +1,5 @@ // ----------------------------------------------------------------------- -// +// // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- diff --git a/Windows/Perspex.Direct2D1/Renderer.cs b/Windows/Perspex.Direct2D1/Renderer.cs index 3454f87941..9af56cdfc1 100644 --- a/Windows/Perspex.Direct2D1/Renderer.cs +++ b/Windows/Perspex.Direct2D1/Renderer.cs @@ -18,9 +18,6 @@ namespace Perspex.Direct2D1 using Matrix = Perspex.Matrix; using Point = Perspex.Point; - /// - /// Renders a . - /// public class Renderer : IRenderer { /// diff --git a/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs b/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs index bd26a5ca98..9173df3821 100644 --- a/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs +++ b/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs @@ -42,6 +42,18 @@ namespace Perspex.Win32.Interop IDC_HELP = 32651 } + [StructLayout(LayoutKind.Sequential)] + public struct PAINTSTRUCT + { + public IntPtr hdc; + public bool fErase; + public RECT rcPaint; + public bool fRestore; + public bool fIncUpdate; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] rgbReserved; + } + [Flags] public enum SetWindowPosFlags : uint { @@ -350,6 +362,9 @@ namespace Perspex.Win32.Interop WM_DISPATCH_WORK_ITEM = WM_USER, } + [DllImport("user32.dll")] + public static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint); + [DllImport("user32.dll")] public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);