From b25ad7a6e15a7284e40407377a1624747ffe42e5 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bruyère Date: Wed, 24 Nov 2021 23:50:38 +0100 Subject: IBackend instead of IDevice to bind to Interface --- Backends/CairoBackend/src/DefaultBackend.cs | 16 +++ Backends/CairoBackend/src/Device.cs | 98 ++------------- Backends/CairoBackend/src/EGLDevice.cs | 7 +- Backends/CairoBackend/src/GLSurface.cs | 2 +- Backends/CairoBackend/src/ImageBackend.cs | 179 ++++++++++++++++++++++++++++ 5 files changed, 208 insertions(+), 94 deletions(-) create mode 100644 Backends/CairoBackend/src/DefaultBackend.cs create mode 100644 Backends/CairoBackend/src/ImageBackend.cs (limited to 'Backends/CairoBackend') diff --git a/Backends/CairoBackend/src/DefaultBackend.cs b/Backends/CairoBackend/src/DefaultBackend.cs new file mode 100644 index 00000000..9ef04b33 --- /dev/null +++ b/Backends/CairoBackend/src/DefaultBackend.cs @@ -0,0 +1,16 @@ +using System; +using Crow.CairoBackend; + +namespace Crow.Backends +{ + public class DefaultBackend : ImageBackend { + /// + /// Create a new generic backend bound to the application surface + /// + /// backend surface width + /// backend surface height + public DefaultBackend (IntPtr nativeWindoPointer, int width, int height) + : base (nativeWindoPointer, width, height) { } + } +} + diff --git a/Backends/CairoBackend/src/Device.cs b/Backends/CairoBackend/src/Device.cs index c87b494b..2efe76ec 100644 --- a/Backends/CairoBackend/src/Device.cs +++ b/Backends/CairoBackend/src/Device.cs @@ -77,18 +77,9 @@ namespace Crow.CairoBackend } public class Device : IDevice { - /// Global font rendering settings for Cairo - FontOptions FontRenderingOptions; - /// Global font rendering settings for Cairo - Antialias Antialias = Antialias.Subpixel; public Device() { - FontRenderingOptions = new FontOptions (); - FontRenderingOptions.Antialias = Antialias.Subpixel; - FontRenderingOptions.HintMetrics = HintMetrics.On; - FontRenderingOptions.HintStyle = HintStyle.Full; - FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default; } ~Device () @@ -106,87 +97,12 @@ namespace Crow.CairoBackend { throw new NotImplementedException(); } - public IRegion CreateRegion () => new Region (); - public virtual ISurface CreateSurface(int width, int height) - => new ImageSurface (Format.ARGB32, width, height); - public virtual ISurface CreateSurface(byte[] data, int width, int height) - => new ImageSurface (data, Format.ARGB32, width, height, 4 * width); - - public virtual ISurface CreateSurface (IntPtr nativeWindoPointer, int width, int height) { - switch (Environment.OSVersion.Platform) { - case PlatformID.Unix: - IntPtr disp = Glfw3.GetX11Display (); - IntPtr nativeWin = Glfw3.GetX11Window (nativeWindoPointer); - Int32 scr = Glfw3.GetX11DefaultScreen (disp); - IntPtr visual = Glfw3.GetX11DefaultVisual (disp, scr); - return new XlibSurface (disp, nativeWin, visual, width, height); - case PlatformID.Win32NT: - case PlatformID.Win32S: - case PlatformID.Win32Windows: - IntPtr hWin32 = Glfw3.GetWin32Window (nativeWindoPointer); - IntPtr hdc = Glfw3.GetWin32DC (hWin32); - return new Win32Surface (hdc); - } - throw new PlatformNotSupportedException ("Unable to create cairo surface."); - } - public virtual IContext CreateContext(ISurface surf) - { - Context gr = new Context (surf); - gr.FontOptions = FontRenderingOptions; - gr.Antialias = Antialias; - return gr; - } - public byte[] LoadBitmap (Stream stream, out Size dimensions) { - byte[] image; -#if STB_SHARP - StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha); - image = new byte[stbi.Data.Length]; - //rgba to argb for cairo. - for (int i = 0; i < stbi.Data.Length; i += 4) { - image[i] = stbi.Data[i + 2]; - image[i + 1] = stbi.Data[i + 1]; - image[i + 2] = stbi.Data[i]; - image[i + 3] = stbi.Data[i + 3]; - } - dimensions = new Size (stbi.Width, stbi.Height); -#else - using (StbImage stbi = new StbImage (stream)) { - image = new byte [stbi.Size]; - for (int i = 0; i < stbi.Size; i+=4) { - //rgba to argb for cairo. ???? looks like bgra to me. - image [i] = Marshal.ReadByte (stbi.Handle, i + 2); - image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1); - image [i + 2] = Marshal.ReadByte (stbi.Handle, i); - image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3); - } - dimensions = new Size (stbi.Width, stbi.Height); - } -#endif - return image; - } - public ISvgHandle LoadSvg(Stream stream) - { - using (BinaryReader sr = new BinaryReader (stream)) - return new SvgHandle (sr.ReadBytes ((int)stream.Length)); - } - public ISvgHandle LoadSvg(string svgFragment) => - new SvgHandle (System.Text.Encoding.Unicode.GetBytes (svgFragment)); - - public IGradient CreateGradient (GradientType gradientType, Rectangle bounds) { - switch (gradientType) { - case GradientType.Vertical: - return new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom); - case GradientType.Horizontal: - return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Top); - case GradientType.Oblic: - return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Bottom); - case GradientType.Radial: - throw new NotImplementedException (); - } - return null; - } + + + + #endregion #region IDispose implementation @@ -198,8 +114,10 @@ namespace Crow.CairoBackend protected virtual void Dispose (bool disposing) { - if (disposing) - FontRenderingOptions.Dispose (); + if (disposing){ + + } + } #endregion } diff --git a/Backends/CairoBackend/src/EGLDevice.cs b/Backends/CairoBackend/src/EGLDevice.cs index 83629374..d9296b74 100644 --- a/Backends/CairoBackend/src/EGLDevice.cs +++ b/Backends/CairoBackend/src/EGLDevice.cs @@ -34,15 +34,16 @@ namespace Crow.CairoBackend { public class EGLDevice : GLDevice { - public EGLDevice (IntPtr dpy, IntPtr gl_ctx, bool threadAwayre = false) : base (NativeMethods.cairo_egl_device_create (dpy, gl_ctx), true) + public EGLDevice (IntPtr dpy, IntPtr gl_ctx, bool threadAwayre = false) + : base (NativeMethods.cairo_egl_device_create (dpy, gl_ctx), true) { SetThreadAware(threadAwayre); } - public override ISurface CreateSurface(int width, int height) + /*public override ISurface CreateSurface(int width, int height) => new ImageSurface (Format.ARGB32, width, height); public override ISurface CreateSurface (IntPtr nativeWindoPointer, int width, int height) { return new GLSurface (this, Glfw.Glfw3.GetEGLSurface (nativeWindoPointer), width, height); - } + }*/ } } diff --git a/Backends/CairoBackend/src/GLSurface.cs b/Backends/CairoBackend/src/GLSurface.cs index c7959dc3..1f486c50 100644 --- a/Backends/CairoBackend/src/GLSurface.cs +++ b/Backends/CairoBackend/src/GLSurface.cs @@ -54,7 +54,7 @@ namespace Crow.CairoBackend { {} public override void Flush () { - base.Flush (); + //base.Flush (); SwapBuffers (); } public override int Width => NativeMethods.cairo_gl_surface_get_width (handle); diff --git a/Backends/CairoBackend/src/ImageBackend.cs b/Backends/CairoBackend/src/ImageBackend.cs new file mode 100644 index 00000000..e390ca98 --- /dev/null +++ b/Backends/CairoBackend/src/ImageBackend.cs @@ -0,0 +1,179 @@ +using System; +using System.IO; +using Drawing2D; +using Glfw; + +namespace Crow.CairoBackend +{ + public class ImageBackend : IBackend { + ISurface surf; + /// Global font rendering settings for Cairo + FontOptions FontRenderingOptions; + /// Global font rendering settings for Cairo + Antialias Antialias = Antialias.Subpixel; + protected ImageBackend () + { + FontRenderingOptions = new FontOptions (); + FontRenderingOptions.Antialias = Antialias.Subpixel; + FontRenderingOptions.HintMetrics = HintMetrics.On; + FontRenderingOptions.HintStyle = HintStyle.Full; + FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default; + } + /// + /// Create a new generic backend bound to the application surface + /// + /// backend surface width + /// backend surface height + public ImageBackend (IntPtr nativeWindoPointer, int width, int height) : this () { + + switch (Environment.OSVersion.Platform) { + case PlatformID.Unix: + IntPtr disp = Glfw3.GetX11Display (); + IntPtr nativeWin = Glfw3.GetX11Window (nativeWindoPointer); + Int32 scr = Glfw3.GetX11DefaultScreen (disp); + IntPtr visual = Glfw3.GetX11DefaultVisual (disp, scr); + surf = new XlibSurface (disp, nativeWin, visual, width, height); + break; + case PlatformID.Win32NT: + case PlatformID.Win32S: + case PlatformID.Win32Windows: + IntPtr hWin32 = Glfw3.GetWin32Window (nativeWindoPointer); + IntPtr hdc = Glfw3.GetWin32DC (hWin32); + surf = new Win32Surface (hdc); + break; + default: + throw new PlatformNotSupportedException ("Unable to create cairo image backend."); + } + } + /// + /// Create a new offscreen backend, used in perfTests + /// + /// backend surface width + /// backend surface height + public ImageBackend (int width, int height) : this () { + surf = new ImageSurface (Format.ARGB32, width, height); + } + ~ImageBackend () + { + Dispose (false); + } + public virtual ISurface CreateSurface(int width, int height) + => new ImageSurface (Format.ARGB32, width, height); + public virtual ISurface CreateSurface(byte[] data, int width, int height) + => new ImageSurface (data, Format.ARGB32, width, height, 4 * width); + public ISurface MainSurface => surf; + public IRegion CreateRegion () => new Region (); + public IContext CreateContext (ISurface surf) + { + Context gr = new Context (surf); + gr.FontOptions = FontRenderingOptions; + gr.Antialias = Antialias; + return gr; + } + //IPattern CreatePattern (PatternType patternType); + public IGradient CreateGradient (GradientType gradientType, Rectangle bounds) + { + switch (gradientType) { + case GradientType.Vertical: + return new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom); + case GradientType.Horizontal: + return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Top); + case GradientType.Oblic: + return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Bottom); + case GradientType.Radial: + throw new NotImplementedException (); + } + return null; + } + public byte[] LoadBitmap (Stream stream, out Size dimensions) + { + byte[] image; +#if STB_SHARP + StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha); + image = new byte[stbi.Data.Length]; + //rgba to argb for cairo. + for (int i = 0; i < stbi.Data.Length; i += 4) { + image[i] = stbi.Data[i + 2]; + image[i + 1] = stbi.Data[i + 1]; + image[i + 2] = stbi.Data[i]; + image[i + 3] = stbi.Data[i + 3]; + } + dimensions = new Size (stbi.Width, stbi.Height); +#else + using (StbImage stbi = new StbImage (stream)) { + image = new byte [stbi.Size]; + for (int i = 0; i < stbi.Size; i+=4) { + //rgba to argb for cairo. ???? looks like bgra to me. + image [i] = Marshal.ReadByte (stbi.Handle, i + 2); + image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1); + image [i + 2] = Marshal.ReadByte (stbi.Handle, i); + image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3); + } + dimensions = new Size (stbi.Width, stbi.Height); + } +#endif + return image; + } + public ISvgHandle LoadSvg(Stream stream) + { + using (BinaryReader sr = new BinaryReader (stream)) + return new SvgHandle (sr.ReadBytes ((int)stream.Length)); + } + public ISvgHandle LoadSvg(string svgFragment) => + new SvgHandle (System.Text.Encoding.Unicode.GetBytes (svgFragment)); + bool disposeContextOnFlush; + IRegion clipping; + protected void clear(IContext ctx) { + for (int i = 0; i < clipping.NumRectangles; i++) + ctx.Rectangle (clipping.GetRectangle (i)); + + ctx.ClipPreserve (); + ctx.Operator = Operator.Clear; + ctx.Fill (); + ctx.Operator = Operator.Over; + } + public IContext PrepareUIFrame(IContext existingContext, IRegion clipping) + { + this.clipping = clipping; + IContext ctx = existingContext; + if (ctx == null) { + disposeContextOnFlush = true; + ctx = new Context (MainSurface); + } else + disposeContextOnFlush = false; + + clear (ctx); + ctx.PushGroup (); + + return ctx; + } + public void FlushUIFrame(IContext ctx) + { + ctx.PopGroupToSource (); + ctx.Paint (); + + if (disposeContextOnFlush) + ctx.Dispose (); + clipping = null; + } + + + #region IDispose implementation + bool isDisposed; + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + protected virtual void Dispose (bool disposing) + { + if (!isDisposed && disposing) { + surf.Dispose (); + FontRenderingOptions.Dispose (); + } + isDisposed = true; + } + #endregion + } +} + -- cgit v1.3.1-4-g156e