]> O.S.I.I.S - jp/crow.git/commitdiff
vkvg backend implementation wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 13 Jul 2021 14:42:44 +0000 (16:42 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Tue, 13 Jul 2021 14:42:44 +0000 (16:42 +0200)
29 files changed:
Crow/Crow.csproj
Crow/src/Fill/BmpPicture.cs
Crow/src/Fill/Gradient.cs
Crow/src/Fill/SvgPicture.cs
Crow/src/GraphicBackends/Mono.Cairo/Region.cs
Crow/src/GraphicBackends/vkvg/Context.cs
Crow/src/GraphicBackends/vkvg/Device.cs
Crow/src/GraphicBackends/vkvg/NativeMethods.cs
Crow/src/GraphicBackends/vkvg/Surface.cs
Crow/src/GraphicBackends/vkvg/VulkanContext.cs [new file with mode: 0644]
Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs [deleted file]
Crow/src/GraphicBackends/vkvg/tmp/Region.cs [new file with mode: 0644]
Crow/src/Interface.cs
Crow/src/Widgets/CircleMeter.cs
Crow/src/Widgets/DockWindow.cs
Crow/src/Widgets/GroupBase.cs
Crow/src/Widgets/OldLabel.cs [deleted file]
Crow/src/Widgets/OldTextBox.cs [deleted file]
Crow/src/Widgets/ScrollingStack.cs
Crow/src/Widgets/TestCairoPatch.cs [deleted file]
Crow/src/Widgets/TextRun.cs [deleted file]
Crow/src/Widgets/Trend.cs [deleted file]
Crow/src/Widgets/Widget.cs
Directory.Build.props
Samples/DebugLogAnalyzer/src/DbgEventWidget.cs
Samples/Directory.Build.props
Samples/HelloWorld/ui/helloworld.crow
Samples/common/src/Editor.cs
Samples/common/src/SampleBase.cs

index e5f2345a9a822ec2ffbaa3ad8a7e0666234eb6d4..e778a55be86dfb01cc1e07e9773a1defa724eedb 100644 (file)
        <PropertyGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
                <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
        </PropertyGroup>
+
        <ItemGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
                <Compile Include="src\GraphicBackends\vkvg\**\*.*" />
+               <PackageReference Include="vke" Version="0.2.0-beta" />
        </ItemGroup>
 
        <ItemGroup Condition=" '$(CrowVkvgBackend)' != 'true'">
index e8df72693fb646327e0c25ea79582078f11b8f46..8284e3a15e84836be84030113661cd7780016df3 100644 (file)
@@ -123,14 +123,21 @@ namespace Crow
                                        widthRatio = heightRatio;
                        }
 
-                       using (ImageSurface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
+#if VKVG
+                       using (Surface tmp = new Surface (iFace.vkvgDevice, bounds.Width, bounds.Height)) {
+#else
+                       using (Surface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
+#endif
                                using (Context gr = new Context (tmp)) {
                                        gr.Translate (bounds.Left, bounds.Top);
                                        gr.Scale (widthRatio, heightRatio);
                                        gr.Translate ((bounds.Width/widthRatio - Dimensions.Width)/2, (bounds.Height/heightRatio - Dimensions.Height)/2);
-
-                                       using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, 
-                                               Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) {
+#if VKVG
+                                       using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref image, Dimensions.Width, Dimensions.Height)) 
+#else
+                                       using (Surface imgSurf = new ImageSurface (image, Format.Argb32, Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) 
+#endif
+                                       {
                                                gr.SetSource (imgSurf, 0,0);
                                                gr.Paint ();
                                        }
@@ -172,9 +179,13 @@ namespace Crow
                        gr.Translate (rect.Left,rect.Top);
                        gr.Scale (widthRatio, heightRatio);
                        gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2);
-                       
-                       using (ImageSurface imgSurf = new ImageSurface (image, Format.Argb32, 
-                               Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) {
+
+#if VKVG
+                       using (Surface imgSurf = new Surface (iFace.vkvgDevice, ref image, Dimensions.Width, Dimensions.Height)) 
+#else
+                       using (Surface imgSurf = new ImageSurface (image, Format.Argb32, Dimensions.Width, Dimensions.Height, 4 * Dimensions.Width)) 
+#endif                 
+                       {
                                gr.SetSource (imgSurf, 0,0);
                                gr.Paint ();
                        }
index 680e1d0fdc46e8cd916c73e62373203c26912af5..ccf8059cfa4be4aa852b9a608d9bd9ac8831718f 100644 (file)
@@ -85,7 +85,7 @@ namespace Crow
 
                public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
                {
-                       Cairo.Gradient grad = null;
+                       /*Cairo.Gradient grad = null;
                        switch (GradientType) {
                        case Type.Vertical:
                                grad = new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);
@@ -107,7 +107,7 @@ namespace Crow
                        }
                        
                        ctx.SetSource (grad);
-                       grad.Dispose ();
+                       grad.Dispose ();*/
                }
                #endregion
 
index 6ce111490180829098b2a90798b67679c31f0991..cd5757675909252d2046f683d4106dd57938cfba 100644 (file)
@@ -86,7 +86,7 @@ namespace Crow
                                        widthRatio = heightRatio;
                        }
 
-                       using (ImageSurface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
+                       /*using (Surface tmp = new ImageSurface (Format.Argb32, bounds.Width, bounds.Height)) {
                                using (Context gr = new Context (tmp)) {
                                        gr.Translate (bounds.Left, bounds.Top);
                                        gr.Scale (widthRatio, heightRatio);
@@ -95,7 +95,7 @@ namespace Crow
                                        hSVG.RenderCairo (gr);
                                }
                                ctx.SetSource (tmp);
-                       }       
+                       }*/     
                }
                #endregion
 
index f2c111d7f0cd5fb8e07efd175abbe2377d737114..e1540089a4faa978e8d9ae1f52f4a6fa5c394d56 100644 (file)
@@ -198,5 +198,6 @@ namespace Crow.Cairo
                        NativeMethods.cairo_region_destroy (Handle);
                        handle = NativeMethods.cairo_region_create ();                  
                }
+               public bool DoesNotContains (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out;
        }
 }
index 482dfe121537c8649c4e377cbe71904533e088ac..870573bad534f51a21c35a4fd12eff27d88f1977 100644 (file)
@@ -72,13 +72,24 @@ namespace vkvg
                                return f_extents;
                        }
                }
-               public TextExtents TextExtents(string s)
-               {
-                       TextExtents extents = default(TextExtents);
-                       if (!string.IsNullOrEmpty(s))
-                               NativeMethods.vkvg_text_extents(handle, TerminateUtf8(s), out extents);
+               public Antialias Antialias {
+                       set;
+                       get;
+               }
+               public TextExtents TextExtents (ReadOnlySpan<char> s, int tabSize = 4) {
+                       TextExtents (s, tabSize, out TextExtents extents);                      
                        return extents;
                }
+               public void TextExtents (ReadOnlySpan<char> s, int tabSize, out TextExtents extents) {
+                       int size = s.Length * 4 + 1;
+                       Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+                       int encodedBytes = Crow.Text.Encoding.ToUtf8 (s, bytes, tabSize);
+                       bytes[encodedBytes] = 0;
+                       TextExtents (bytes.Slice (0, encodedBytes + 1), out extents);
+               }               
+               public void TextExtents (Span<byte> bytes, out TextExtents extents) {
+                       NativeMethods.vkvg_text_extents (handle, ref bytes.GetPinnableReference (), out extents);
+               }
                public Matrix Matrix
                {
                        get
@@ -92,10 +103,17 @@ namespace vkvg
                                NativeMethods.vkvg_set_matrix(handle, ref value);
                        }
                }
-               public void ShowText(string txt)
-               {
-                       NativeMethods.vkvg_show_text(handle, TerminateUtf8(txt));
+               public void ShowText (ReadOnlySpan<char> s, int tabSize) {
+                       int size = s.Length * 4 + 1;
+                       Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+                       int encodedBytes = Crow.Text.Encoding.ToUtf8 (s, bytes, tabSize);
+                       bytes[encodedBytes] = 0;
+                       ShowText (bytes.Slice (0, encodedBytes + 1));
                }
+               public void ShowText (Span<byte> bytes) {
+                       NativeMethods.vkvg_show_text (handle, ref bytes.GetPinnableReference());
+               }
+
                public void ShowText(TextRun textRun)
                {
                        NativeMethods.vkvg_show_text_run(handle, textRun.Handle);
@@ -120,6 +138,7 @@ namespace vkvg
                {
                        NativeMethods.vkvg_paint(handle);
                }
+               public void PaintWithAlpha (double alpha) => Paint();
                public void Arc(float xc, float yc, float radius, float a1, float a2)
                {
                        NativeMethods.vkvg_arc(handle, xc, yc, radius, a1, a2);
@@ -128,6 +147,15 @@ namespace vkvg
                {
                        NativeMethods.vkvg_arc(handle, (float)xc, (float)yc, (float)radius, (float)a1, (float)a2);
                }
+               public void Arc (PointD center, double radius, double angle1, double angle2)
+               {
+                       NativeMethods.vkvg_arc (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2);
+               }
+
+               public void ArcNegative (PointD center, double radius, double angle1, double angle2)
+               {
+                       NativeMethods.vkvg_arc_negative (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2);
+               }               
                public void ArcNegative(float xc, float yc, float radius, float a1, float a2)
                {
                        NativeMethods.vkvg_arc_negative(handle, xc, yc, radius, a1, a2);
@@ -307,6 +335,7 @@ namespace vkvg
                {
                        NativeMethods.vkvg_render_svg(handle, nsvgImage, subId);
                }
+               public Crow.Rectangle StrokeExtents () => default;
                internal static byte[] TerminateUtf8(string s)
                {
                        // compute the byte count including the trailing \0
@@ -326,6 +355,15 @@ namespace vkvg
                                        NativeMethods.vkvg_set_dash(handle, value, (uint)value.Length, 0);
                        }
                }
+               
+
+               public void PushGroup () {
+
+               }
+               public void PopGroupToSource () {
+                       
+               }
+
                #region IDisposable implementation
                public void Dispose()
                {
index 84eea519bd654b9e11762d57a392baa2d75ca1fd..a50e366d4eb1030426b187933c5f3b98d24dbd29 100644 (file)
@@ -22,18 +22,12 @@ namespace vkvg
                }
                #endregion
 
-               public void GetDpy (out int hdpy, out int vdpy) {
-                       NativeMethods.vkvg_device_get_dpy (handle, out hdpy, out vdpy);
-               }
-               public void SetDpy (int hdpy, int vdpy) {
-                       NativeMethods.vkvg_device_set_dpy (handle, hdpy, vdpy);
-               }
-               public void AddReference () {
-                       NativeMethods.vkvg_device_reference (handle);
-               }
+               public void GetDpy (out int hdpy, out int vdpy) => NativeMethods.vkvg_device_get_dpy (handle, out hdpy, out vdpy);
+               public void SetDpy (int hdpy, int vdpy) => NativeMethods.vkvg_device_set_dpy (handle, hdpy, vdpy);
+               public void AddReference () => NativeMethods.vkvg_device_reference (handle);
                public uint References () => NativeMethods.vkvg_device_get_reference_count (handle);
 
-               public IntPtr Handle { get { return handle; }}
+               public IntPtr Handle => handle;
 
                #region IDisposable implementation
                public void Dispose ()
index 48f2eb6bbebf0caf4ec5f663856ad8d2301d97bd..1a6335211910d151f7d2038ef45ba7768e1133c2 100644 (file)
@@ -116,12 +116,15 @@ namespace vkvg
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
         internal static extern void vkvg_text_extents(IntPtr ctx, byte[] utf8, out TextExtents extents);
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void vkvg_text_extents(IntPtr cr, ref byte utf8, out TextExtents extents);
+        [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
         internal static extern void vkvg_select_font_face(IntPtr ctx, string name);
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
         internal static extern void vkvg_set_font_size(IntPtr ctx, uint size);
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
         internal static extern void vkvg_show_text(IntPtr ctx, byte [] utf8);
-
+        [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void vkvg_show_text(IntPtr cr, ref byte utf8);
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
         internal static extern void vkvg_save(IntPtr ctx);
         [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
index 79f92dcd1a5fcbec6c59d4f70621f0d8c206d220..98a563c7173bad678d1596f75b476d06ab32de31 100644 (file)
@@ -36,14 +36,12 @@ namespace vkvg
                        Dispose (false);
                }
 
-               public IntPtr Handle { get { return handle; }}
-               public IntPtr VkImage { get { return NativeMethods.vkvg_surface_get_vk_image (handle); }}
-               public int Width { get { return NativeMethods.vkvg_surface_get_width (handle); }}
-               public int Height { get { return NativeMethods.vkvg_surface_get_height (handle); }}
+               public IntPtr Handle => handle;
+               public IntPtr VkImage => NativeMethods.vkvg_surface_get_vk_image (handle);
+               public int Width => NativeMethods.vkvg_surface_get_width (handle);
+               public int Height => NativeMethods.vkvg_surface_get_height (handle);
 
-               public void AddReference () {
-                       NativeMethods.vkvg_surface_reference (handle);
-               }
+               public void AddReference () => NativeMethods.vkvg_surface_reference (handle);
                public uint References () => NativeMethods.vkvg_surface_get_reference_count (handle);
 
 //             public Surface CreateSimilar (uint width, uint height) {
diff --git a/Crow/src/GraphicBackends/vkvg/VulkanContext.cs b/Crow/src/GraphicBackends/vkvg/VulkanContext.cs
new file mode 100644 (file)
index 0000000..3957912
--- /dev/null
@@ -0,0 +1,182 @@
+// Copyright (c) 2019  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Runtime.InteropServices;
+using Glfw;
+using vke;
+using Vulkan;
+using static Vulkan.Vk;
+using Device = vke.Device;
+
+namespace vkvg {
+       /// <summary>
+       /// Base class to build vulkan application.
+       /// Provide default swapchain with its command pool and buffers per image and the main present queue
+       /// </summary>
+       public class VulkanContext : IDisposable {
+
+               /** GLFW window native pointer. */
+               IntPtr hWin;
+               /**Vulkan Surface */
+               protected VkSurfaceKHR hSurf;
+               /**vke Instance encapsulating a VkInstance. */
+               protected Instance instance;    
+               /**vke Physical device associated with this window*/
+               protected PhysicalDevice phy;
+               /**vke logical device */                        
+               protected vke.Device dev;
+               protected PresentQueue presentQueue;
+               protected SwapChain swapChain;
+               protected CommandPool cmdPool;
+               protected PrimaryCommandBuffer[] cmds;
+               protected VkSemaphore[] drawComplete;
+               protected Fence drawFence;
+
+               protected uint fps { get; private set; }
+               protected bool updateViewRequested = true;
+
+               /// <summary>readonly GLFW window handle</summary>
+               public IntPtr WindowHandle => hWin;
+
+               uint frameCount;
+               Stopwatch frameChrono;
+
+               string[] EnabledInstanceExtensions => null;
+
+               string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain };
+
+               uint width, height;
+
+               public VulkanContext (IntPtr hWin, uint _width, uint _height, bool vsync = false) {
+                       this.hWin = hWin;
+
+                       List<string> instExts = new List<string> (Glfw3.GetRequiredInstanceExtensions ());
+                       if (EnabledInstanceExtensions != null)
+                               instExts.AddRange (EnabledInstanceExtensions);
+
+                       instance = new Instance (instExts.ToArray());
+                       hSurf = instance.CreateSurface (hWin);
+
+                       phy = instance.GetAvailablePhysicalDevice ().FirstOrDefault (p => p.HasSwapChainSupport);
+
+                       VkPhysicalDeviceFeatures enabledFeatures = default;
+
+                       //First create the c# device class
+                       dev = new vke.Device (phy);
+
+                       presentQueue = new PresentQueue (dev, VkQueueFlags.Graphics, hSurf);
+
+                       //activate the device to have effective queues created accordingly to what's available
+                       dev.Activate (enabledFeatures, EnabledDeviceExtensions);
+
+                       swapChain = new SwapChain (presentQueue as PresentQueue, _width, _height, SwapChain.PREFERED_FORMAT,
+                               vsync ? VkPresentModeKHR.FifoKHR : VkPresentModeKHR.ImmediateKHR);
+                       swapChain.Activate ();
+
+                       width = swapChain.Width;
+                       height = swapChain.Height;
+
+                       cmdPool = new CommandPool (dev, presentQueue.qFamIndex, VkCommandPoolCreateFlags.ResetCommandBuffer);
+                       cmds = cmdPool.AllocateCommandBuffer (swapChain.ImageCount);
+
+                       drawComplete = new VkSemaphore[swapChain.ImageCount];
+                       drawFence = new Fence (dev, true, "draw fence");
+
+                       for (int i = 0; i < swapChain.ImageCount; i++) {
+                               drawComplete[i] = dev.CreateSemaphore ();
+                               drawComplete[i].SetDebugMarkerName (dev, "Semaphore DrawComplete" + i);
+                       }
+
+                       cmdPool.SetName ("main CmdPool");                       
+               }
+
+               public vkvg.Device CreateVkvgDevice () => 
+                       new vkvg.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex);
+
+               internal vke.Image blitSource;
+               
+               public void BuildBlitCommand (vkvg.Surface surf) {
+                       
+                       blitSource = new vke.Image (dev, new VkImage((ulong)surf.VkImage.ToInt64()), Vulkan.VkFormat.R8g8b8a8Unorm,
+                               Vulkan.VkImageUsageFlags.TransferSrc | Vulkan.VkImageUsageFlags.TransferDst | Vulkan.VkImageUsageFlags.ColorAttachment,
+                               width, height);
+
+                       for (int i = 0; i < swapChain.ImageCount; i++) {
+                               vke.Image blitDest = swapChain.images[i];
+                               vke.PrimaryCommandBuffer cmd = cmds[i];
+                               cmd.Start();
+                               
+                               blitDest.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferDstOptimal);
+                               blitSource.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.TransferSrcOptimal);
+
+                               blitSource.BlitTo (cmd, blitDest, VkFilter.Nearest);
+
+                               blitDest.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.PresentSrcKHR);
+                               blitSource.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.ColorAttachmentOptimal);
+
+                               cmd.End ();
+                       }
+               }
+               /// <summary>
+               /// Main render method called each frame. get next swapchain image, process resize if needed, submit and present to the presentQueue.
+               /// Wait QueueIdle after presenting.
+               /// </summary>
+               public void render () {
+                       int idx = swapChain.GetNextImage ();
+                       if (idx < 0) {
+                               width = swapChain.Width;
+                               height = swapChain.Height;
+                               return;
+                       }
+
+                       if (cmds[idx] == null)
+                               return;
+
+                       drawFence.Wait ();
+                       drawFence.Reset ();
+
+                       presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence);
+                       presentQueue.Present (swapChain, drawComplete[idx]);                    
+               }
+
+               #region IDisposable Support
+               protected bool isDisposed;
+
+               protected virtual void Dispose (bool disposing) {
+                       if (!isDisposed) {
+                               dev.WaitIdle ();
+
+                               for (int i = 0; i < swapChain.ImageCount; i++) {
+                                       dev.DestroySemaphore (drawComplete[i]);
+                                       cmds[i].Free ();
+                               }
+                               drawFence.Dispose ();
+                               swapChain.Dispose ();
+
+                               vkDestroySurfaceKHR (instance.Handle, hSurf, IntPtr.Zero);
+
+                               if (disposing) {
+                                       cmdPool.Dispose ();
+                                       dev.Dispose ();
+                                       instance.Dispose ();
+                               } else
+                                       Debug.WriteLine ("a VkWindow has not been correctly disposed");
+
+                               isDisposed = true;
+                       }
+               }
+
+               ~VulkanContext () {
+                       Dispose (false);
+               }
+               public void Dispose () {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+               #endregion
+       }
+}
diff --git a/Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs b/Crow/src/GraphicBackends/vkvg/tmp/Rectangles.cs
deleted file mode 100644 (file)
index c50236c..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System.Collections.Generic;
-using vkvg;
-
-namespace Crow {
-       public enum RegionOverlap {
-               In,
-               Out,
-               Part,
-       }       
-       public class Region
-    {
-        public List<Rectangle> list = new List<Rectangle>();
-        public int count
-        {
-            get { return list.Count; }
-        }
-               public bool IsEmpty => list.Count == 0;
-
-        public void AddRectangle(Rectangle r)
-        {
-                       if (doesNotContain (r)) {
-                               list.Add (r);
-                               boundsUpToDate = false;
-                       }
-        }
-        public void Reset()
-        {
-            list = new List<Rectangle>();
-                       _bounds = default;
-                       boundsUpToDate = true;
-        }
-        bool doesNotContain(Rectangle r)
-        {
-            foreach (Rectangle rInList in list)
-                if (rInList.ContainsOrIsEqual(r))
-                    return false;
-            return true;
-        }
-
-        public bool intersect(Rectangle r)
-        {
-            foreach (Rectangle rInList in list)
-                if (rInList.Intersect(r))
-                    return true;
-            return false;
-        }
-               public void stroke(Context ctx, Color c)
-               {
-                       foreach (Rectangle r in list)
-                               ctx.Rectangle(r);
-
-                       ctx.SetSource(c);
-
-                       ctx.LineWidth = 2;
-                       ctx.Stroke ();
-               }
-        public void clearAndClip(Context ctx)
-        {
-                       if (list.Count == 0)
-                               return;
-            foreach (Rectangle r in list)
-                ctx.Rectangle(r);
-
-                       ctx.ClipPreserve();
-                       ctx.Operator = Operator.Clear;
-            ctx.Fill();
-            ctx.Operator = Operator.Over;
-        }
-
-        public void clip(Context ctx)
-        {
-            foreach (Rectangle r in list)
-               ctx.Rectangle(r);
-
-            ctx.Clip();
-        }
-
-               Rectangle _bounds;
-               bool boundsUpToDate = true;
-               public Rectangle Bounds {
-                       get {
-                               if (!boundsUpToDate) {
-                                       if (list.Count > 0) {
-                                               _bounds = list [0];
-                                               for (int i = 1; i < list.Count; i++) {
-                                                       _bounds += list [i];
-                                               }
-                                       } else
-                                               _bounds = default;
-                                       boundsUpToDate = true;
-                               }
-                               return _bounds;
-                       }
-               }
-               public void clear(Context ctx)
-        {
-            foreach (Rectangle r in list)
-                ctx.Rectangle(r);
-            ctx.Operator = Operator.Clear;
-            ctx.Fill();
-            ctx.Operator = Operator.Over;
-        }
-               public override string ToString ()
-               {
-                       string tmp = "";
-                       foreach (Rectangle r in list) {
-                               tmp += r.ToString ();
-                       }
-                       return tmp;
-               }
-    }
-}
diff --git a/Crow/src/GraphicBackends/vkvg/tmp/Region.cs b/Crow/src/GraphicBackends/vkvg/tmp/Region.cs
new file mode 100644 (file)
index 0000000..2d061e6
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (c) 2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
+
+using System.Collections.Generic;
+using vkvg;
+using System;
+
+namespace Crow {
+       public enum RegionOverlap {
+               In,
+               Out,
+               Part,
+       }       
+       public class Region : IDisposable
+    {
+        public List<Rectangle> list = new List<Rectangle>();
+        public int count => list.Count;
+               public int NumRectangles => list.Count;
+               public bool IsEmpty => list.Count == 0;
+               public Rectangle GetRectangle(int i) => list[i];
+
+        public void AddRectangle(Rectangle r)
+        {
+                       if (DoesNotContains (r)) {
+                               list.Add (r);
+                               boundsUpToDate = false;
+                       }
+        }
+        public void Reset()
+        {
+            list = new List<Rectangle>();
+                       _bounds = default;
+                       boundsUpToDate = true;
+        }
+        public bool DoesNotContains(Rectangle r)
+        {
+            foreach (Rectangle rInList in list)
+                if (rInList.ContainsOrIsEqual(r))
+                    return false;
+            return true;
+        }              
+
+        public bool intersect(Rectangle r)
+        {
+            foreach (Rectangle rInList in list)
+                if (rInList.Intersect(r))
+                    return true;
+            return false;
+        }
+               public void stroke(Context ctx, Color c)
+               {
+                       foreach (Rectangle r in list)
+                               ctx.Rectangle(r);
+
+                       ctx.SetSource(c);
+
+                       ctx.LineWidth = 2;
+                       ctx.Stroke ();
+               }
+        public void clearAndClip(Context ctx)
+        {
+                       if (list.Count == 0)
+                               return;
+            foreach (Rectangle r in list)
+                ctx.Rectangle(r);
+
+                       ctx.ClipPreserve();
+                       ctx.Operator = Operator.Clear;
+            ctx.Fill();
+            ctx.Operator = Operator.Over;
+        }
+
+        public void clip(Context ctx)
+        {
+            foreach (Rectangle r in list)
+               ctx.Rectangle(r);
+
+            ctx.Clip();
+        }
+               public void UnionRectangle (Rectangle r) {
+                       AddRectangle (r);
+               }
+               Rectangle _bounds;
+               bool boundsUpToDate = true;
+               public Rectangle Bounds {
+                       get {
+                               if (!boundsUpToDate) {
+                                       if (list.Count > 0) {
+                                               _bounds = list [0];
+                                               for (int i = 1; i < list.Count; i++) {
+                                                       _bounds += list [i];
+                                               }
+                                       } else
+                                               _bounds = default;
+                                       boundsUpToDate = true;
+                               }
+                               return _bounds;
+                       }
+               }
+               public void clear(Context ctx)
+        {
+            foreach (Rectangle r in list)
+                ctx.Rectangle(r);
+            ctx.Operator = Operator.Clear;
+            ctx.Fill();
+            ctx.Operator = Operator.Over;
+        }
+               public override string ToString ()
+               {
+                       string tmp = "";
+                       foreach (Rectangle r in list) {
+                               tmp += r.ToString ();
+                       }
+                       return tmp;
+               }
+
+               public void Dispose()
+               {
+                       
+               }
+       }
+}
index add783544508350b8cd9a243e7b01fae931a8345..e23c7afa5b668c7b3c9f123de78d0c66fcc1b37a 100644 (file)
@@ -183,7 +183,11 @@ namespace Crow
                        Glfw3.SetWindowSizeCallback (hWin, HandleWindowSizeDelegate);
                        Glfw3.SetWindowRefreshCallback (hWin, HandleWindowRefreshDelegate);
                }
-
+#if VKVG
+               VulkanContext vkCtx;
+               internal Device vkvgDevice;
+               vke.Image vkvgSurfaceImage;
+#endif
                protected void initSurface ()
                {
                        Glfw3.Init ();
@@ -199,6 +203,12 @@ namespace Crow
 
                        registerGlfwCallbacks ();
 
+#if VKVG
+                       vkCtx = new VulkanContext (hWin, (uint)clientRectangle.Width, (uint)clientRectangle.Height);
+                       vkvgDevice = vkCtx.CreateVkvgDevice ();
+                       surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
+                       vkCtx.BuildBlitCommand (surf);
+#else
                        switch (Environment.OSVersion.Platform) {
                        case PlatformID.MacOSX:
                                break;
@@ -220,6 +230,7 @@ namespace Crow
                        case PlatformID.WinCE:
                                throw new PlatformNotSupportedException ("Unable to create cairo surface.");
                        }
+#endif
                }
 
                public void SetWindowIcon (string path) {
@@ -1135,7 +1146,7 @@ namespace Crow
                                        Widget p = GraphicTree[i];
                                        if (!p.IsVisible)
                                                continue;
-                                       if (clipping.Contains (p.Slot) == RegionOverlap.Out)
+                                       if (clipping.DoesNotContains (p.Slot))
                                                continue;
 
                                        //ctx.Save ();
@@ -1168,6 +1179,9 @@ namespace Crow
                                ctx.Stroke ();
 #endif
 
+#if VKVG
+                               vkCtx.render ();
+#else
                                ctx.PopGroupToSource ();
 
                                if (!SolidBackground)
@@ -1176,7 +1190,7 @@ namespace Crow
                                ctx.Paint ();
 
                                surf.Flush ();
-
+#endif
                                
                                clipping.Reset ();
 
@@ -1184,6 +1198,10 @@ namespace Crow
                                IsDirty = true;
                        }
 
+#if VKVG
+                               vkCtx.render ();
+#endif
+
                        drawTextCursor (ctx);
 
                        debugHighlightFocus (ctx);
@@ -1364,6 +1382,12 @@ namespace Crow
                        lock (UpdateMutex) {
                                clientRectangle = bounds;
 
+#if VKVG
+                               vkCtx.blitSource?.Dispose ();
+                               surf?.Dispose ();
+                               surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);                         
+                               vkCtx.BuildBlitCommand (surf);                          
+#else
                                switch (Environment.OSVersion.Platform) {
                                case PlatformID.MacOSX:
                                        break;
@@ -1385,7 +1409,7 @@ namespace Crow
                                case PlatformID.WinCE:
                                        throw new PlatformNotSupportedException ("Unable to create cairo surface.");
                                }
-
+#endif
                                foreach (Widget g in GraphicTree)
                                        g.RegisterForLayouting (LayoutingType.All);
 
index 6e3e67c6b4329ed8098443ced7de4410d1403302..a056d78cbf0556c3f8b867cf4ff087ac14a417be 100644 (file)
@@ -4,8 +4,11 @@
 
 using System;
 using System.ComponentModel;
+#if VKVG
+using vkvg;
+#else
 using Crow.Cairo;
-
+#endif
 namespace Crow {
 
 public class CircleMeter : Gauge {
index 522ff83f7f86834bb79c788e1b85a68907963f8a..ae085cca0320d23f5aeb67471c4f2ef888cd5aab 100644 (file)
@@ -202,8 +202,8 @@ namespace Crow
                                        r.Inflate (r.Width / -3, r.Height / -3);
                                        break;
                                }
-                   Surface dragImg = IFace.surf.CreateSimilar (Crow.Cairo.Content.ColorAlpha,  r.Width, r.Height);
-                               using (Crow.Cairo.Context gr = new Crow.Cairo.Context(dragImg)) {
+                   /*Surface dragImg = IFace.surf.CreateSimilar (Content.ColorAlpha,   r.Width, r.Height);
+                               using (Context gr = new Context(dragImg)) {
                                        gr.LineWidth = 1;
                                        gr.Rectangle (0,0,r.Width,r.Height);
                                        gr.SetSource (0.2,0.3,0.9,0.5);
@@ -211,7 +211,7 @@ namespace Crow
                                        gr.SetSource (0.1,0.2,1);
                                        gr.Stroke ();
                                }
-                               IFace.CreateDragImage (dragImg, r, false);
+                               IFace.CreateDragImage (dragImg, r, false);*/
                        }
                }
         protected override void onDragEnter (object sender, DragDropEventArgs e) {
index 81aa82f4e002f76f96f29f77dd99d3b9e9505078..6387048fc303e515b984a7607ad06088dbac59e3 100644 (file)
@@ -274,7 +274,7 @@ namespace Crow
                                                foreach (Widget c in Children) {
                                                        if (!c.IsVisible)
                                                                continue;
-                                                       if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out)
+                                                       if (Clipping.DoesNotContains (c.Slot + ClientRectangle.Position))
                                                                continue;
                                                        c.Paint (gr);
                                                }
diff --git a/Crow/src/Widgets/OldLabel.cs b/Crow/src/Widgets/OldLabel.cs
deleted file mode 100644 (file)
index c0c9470..0000000
+++ /dev/null
@@ -1,850 +0,0 @@
-// Copyright (c) 2013-2019  Bruyère Jean-Philippe jp_bruyere@hotmail.com
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-using System.Text.RegularExpressions;
-using System.ComponentModel;
-
-namespace Crow {
-       [Obsolete]
-       public class OldLabel : Widget
-    {
-               #region CTOR
-               protected OldLabel () {}
-               public OldLabel(Interface iface, string style = null) : base (iface, style) { }
-               #endregion
-
-               public event EventHandler<TextChangeEventArgs> TextChanged;
-
-               public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
-               {
-                       textMeasureIsUpToDate = false;
-                       NotifyValueChanged ("Text", Text);
-                       TextChanged.Raise (this, e);
-               }
-        //TODO:change protected to private
-
-               #region private and protected fields
-               string _text = "label";
-        Alignment _textAlignment;
-               bool horizontalStretch;
-               bool verticalStretch;
-               bool _selectable;
-               bool _multiline;
-               Color selBackground;
-               Color selForeground;
-               Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
-               int _currentCol;        //0 based cursor position in string
-               int _currentLine;
-               Point _selBegin = -1;   //selection start (row,column)
-               Point _selRelease = -1; //selection end (row,column)
-               double textCursorPos;   //cursor position in cairo units in widget client coord.
-               double SelStartCursorPos = -1;
-               double SelEndCursorPos = -1;
-               bool SelectionInProgress = false;
-
-        protected Rectangle rText;
-               protected float widthRatio = 1f;
-               protected float heightRatio = 1f;
-               protected FontExtents fe;
-               protected TextExtents te;
-               #endregion
-
-               [DefaultValue("SteelBlue")]
-               public virtual Color SelectionBackground {
-                       get { return selBackground; }
-                       set {
-                               if (selBackground == value)
-                                       return;
-                               selBackground = value;
-                               NotifyValueChangedAuto (selBackground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue("White")]
-               public virtual Color SelectionForeground {
-                       get { return selForeground; }
-                       set {
-                               if (selForeground == value)
-                                       return;
-                               selForeground = value;
-                               NotifyValueChangedAuto (selForeground);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(Alignment.Left)]
-               public Alignment TextAlignment
-        {
-            get { return _textAlignment; }
-            set {
-                               if (value == _textAlignment)
-                                       return;
-                               _textAlignment = value;
-                               RegisterForRedraw ();
-                               NotifyValueChangedAuto (_textAlignment);
-                       }
-        }
-               [DefaultValue(false)]
-               public virtual bool HorizontalStretch {
-                       get { return horizontalStretch; }
-                       set {
-                               if (horizontalStretch == value)
-                                       return;
-                               horizontalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChangedAuto (horizontalStretch);
-                       }
-               }
-               [DefaultValue(false)]
-               public virtual bool VerticalStretch {
-                       get { return verticalStretch; }
-                       set {
-                               if (verticalStretch == value)
-                                       return;
-                               verticalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChangedAuto (verticalStretch);
-                       }
-               }
-               [DefaultValue("label")]
-        public string Text
-        {
-            get {
-                               return lines == null ?
-                                       _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
-                       }
-            set
-            {
-                               if (string.Equals (value, _text, StringComparison.Ordinal))
-                    return;
-
-                _text = value;
-
-                               if (string.IsNullOrEmpty(_text))
-                                       _text = "";
-
-                               lines = getLines;
-
-                               OnTextChanged (this, new TextChangeEventArgs (default));
-                               RegisterForGraphicUpdate ();
-            }
-        }
-               [DefaultValue(false)]
-               public bool Selectable
-               {
-                       get { return _selectable; }
-                       set
-                       {
-                               if (value == _selectable)
-                                       return;
-                               _selectable = value;
-                               NotifyValueChangedAuto (_selectable);
-                               SelBegin = -1;
-                               SelRelease = -1;
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(false)]
-               public bool Multiline
-               {
-                       get { return _multiline; }
-                       set
-                       {
-                               if (value == _multiline)
-                                       return;
-                               _multiline = value;
-                               NotifyValueChangedAuto (_multiline);
-                               RegisterForGraphicUpdate();
-                       }
-               }
-               [DefaultValue(0)]
-               public int CurrentColumn{
-                       get { return _currentCol; }
-                       set {
-                               if (value == _currentCol)
-                                       return;
-                               if (value < 0)
-                                       _currentCol = 0;
-                               else if (value > lines [_currentLine].Length)
-                                       _currentCol = lines [_currentLine].Length;
-                               else
-                                       _currentCol = value;
-                               NotifyValueChangedAuto (_currentCol);
-
-                               Rectangle cb = ClientRectangle;
-
-                               if (Width == Measure.Fit || cb.Width >= cachedTextSize.Width) {
-                                       xTranslation = 0;
-                                       return;
-                               }
-                               int xpos = xposition;
-                               if (xTranslation + xpos > cb.Width)
-                                       xTranslation = cb.Width - xpos;
-                               else if (xpos < -xTranslation)
-                                       xTranslation = -xpos;
-                               RegisterForRedraw ();
-                       }
-               }
-               int xTranslation = 0;
-               int xposition {
-                       get {
-                               using (Context gr = new Context (IFace.surf)) {
-                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
-                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                                       gr.SetFontSize (Font.Size);
-                                       gr.FontOptions = Interface.FontRenderingOptions;
-                                       gr.Antialias = Interface.Antialias;
-                                       try {
-                                               string l = lines [_currentLine];
-                                               if (_currentCol < l.Length)
-                                                       l = l.Remove (Math.Min (_currentCol, l.Length));
-                                               l = l.Replace ("\t", new String (' ', Interface.TAB_SIZE));
-                                               return (int)Math.Ceiling (gr.TextExtents (l).XAdvance);
-                                       } catch {
-                                               System.Diagnostics.Debug.WriteLine ("xpos measuring fault in label");
-                                               return 0;
-                                       }
-                               }
-                       }
-               }
-
-               [DefaultValue(0)]
-               public int CurrentLine{
-                       get { return _currentLine; }
-                       set {
-                               if (value == _currentLine)
-                                       return;
-                               if (value >= lines.Count)
-                                       _currentLine = lines.Count-1;
-                               else if (value < 0)
-                                       _currentLine = 0;
-                               else
-                                       _currentLine = value;
-                               //force recheck of currentCol for bounding
-                               int cc = _currentCol;
-                               _currentCol = 0;
-                               CurrentColumn = cc;
-                               NotifyValueChangedAuto (_currentLine);
-                       }
-               }
-               [XmlIgnore]public Point CurrentPosition {
-                       get { return new Point(_currentCol, CurrentLine); }
-               }
-               //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work
-               /// <summary>
-               /// Selection begin position in char units
-               /// </summary>
-               [DefaultValue("-1")]
-               public Point SelBegin {
-                       get {
-                               return _selBegin;
-                       }
-                       set {
-                               if (value == _selBegin)
-                                       return;
-                               _selBegin = value;
-                               NotifyValueChangedAuto (_selBegin);
-                               NotifyValueChanged ("SelectedText", SelectedText);
-                       }
-               }
-               [DefaultValue("-1")]
-               public Point SelRelease {
-                       get {
-                               return _selRelease;
-                       }
-                       set {
-                               if (value == _selRelease)
-                                       return;
-                               _selRelease = value;
-                               NotifyValueChangedAuto (_selRelease);
-                               NotifyValueChanged ("SelectedText", SelectedText);
-                       }
-               }
-               /// <summary>
-               /// return char at CurrentLine, CurrentColumn
-               /// </summary>
-               [XmlIgnore]protected Char CurrentChar
-               {
-                       get {
-                               return lines [CurrentLine][CurrentColumn];
-                       }
-               }
-               /// <summary>
-               /// ordered selection start and end positions in char units
-               /// </summary>
-               [XmlIgnore]protected Point selectionStart
-               {
-                       get {
-                               return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
-                                       SelBegin.Y > SelRelease.Y ? SelRelease :
-                                       SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
-                       }
-               }
-               [XmlIgnore]public Point selectionEnd
-               {
-                       get {
-                               return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
-                                       SelBegin.Y < SelRelease.Y ? SelRelease :
-                                       SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
-                       }
-               }
-               [XmlIgnore]public string SelectedText
-               {
-                       get {
-                               if (SelRelease < 0 || SelBegin < 0)
-                                       return "";
-                               if (selectionStart.Y == selectionEnd.Y)
-                                       return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
-                               string tmp = "";
-                               tmp = lines [selectionStart.Y].Substring (selectionStart.X);
-                               for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
-                                       tmp += Interface.LineBreak + lines [l];
-                               }
-                               tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
-                               return tmp;
-                       }
-               }
-               [XmlIgnore]public bool selectionIsEmpty
-               { get { return SelRelease < 0; } }
-
-               List<string> lines;
-               List<string> getLines {
-                       get {
-                               return _multiline ?
-                                       Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() :
-                                       new List<string>(new string[] { _text });
-                       }
-               }
-               /// <summary>
-               /// Moves cursor one char to the left.
-               /// </summary>
-               /// <returns><c>true</c> if move succeed</returns>
-               public bool MoveLeft(){
-                       int tmp = _currentCol - 1;
-                       if (tmp < 0) {
-                               if (_currentLine == 0)
-                                       return false;
-                               CurrentLine--;
-                               CurrentColumn = int.MaxValue;
-                       } else
-                               CurrentColumn = tmp;
-                       return true;
-               }
-               /// <summary>
-               /// Moves cursor one char to the right.
-               /// </summary>
-               /// <returns><c>true</c> if move succeed</returns>
-               public bool MoveRight(){
-                       int tmp = _currentCol + 1;
-                       if (tmp > lines [_currentLine].Length){
-                               if (CurrentLine == lines.Count - 1)
-                                       return false;
-                               CurrentLine++;
-                               CurrentColumn = 0;
-                       } else
-                               CurrentColumn = tmp;
-                       return true;
-               }
-               public void GotoWordStart(){
-                       CurrentColumn--;
-                       //skip white spaces
-                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
-                               CurrentColumn--;
-                       while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0)
-                               CurrentColumn--;
-                       if (!char.IsLetterOrDigit (this.CurrentChar))
-                               CurrentColumn++;
-               }
-               public void GotoWordEnd(){
-                       //skip white spaces
-                       if (CurrentColumn >= lines [CurrentLine].Length - 1)
-                               return;
-                       while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
-                               CurrentColumn++;
-                       while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
-                               CurrentColumn++;
-                       if (char.IsLetterOrDigit (this.CurrentChar))
-                               CurrentColumn++;
-               }
-               public void DeleteChar()
-               {
-                       if (selectionIsEmpty) {
-                               if (CurrentColumn == 0) {
-                                       if (CurrentLine == 0 && lines.Count == 1)
-                                               return;
-                                       CurrentLine--;
-                                       CurrentColumn = lines [CurrentLine].Length;
-                                       lines [CurrentLine] += lines [CurrentLine + 1];
-                                       lines.RemoveAt (CurrentLine + 1);
-
-                                       OnTextChanged (this, new TextChangeEventArgs (default));
-                                       return;
-                               }
-                               CurrentColumn--;
-                               lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
-                       } else {
-                               int linesToRemove = selectionEnd.Y - selectionStart.Y + 1;
-                               int l = selectionStart.Y;
-
-                               if (linesToRemove > 0) {
-                                       lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
-                                               lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
-                                       l++;
-                                       for (int c = 0; c < linesToRemove-1; c++)
-                                               lines.RemoveAt (l);
-                                       CurrentLine = selectionStart.Y;
-                                       CurrentColumn = selectionStart.X;
-                               } else
-                                       lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
-                               CurrentColumn = selectionStart.X;
-                               SelBegin = -1;
-                               SelRelease = -1;
-                       }
-                       OnTextChanged (this, new TextChangeEventArgs (default));
-               }
-               /// <summary>
-               /// Insert new string at caret position, should be sure no line break is inside.
-               /// </summary>
-               /// <param name="str">String.</param>
-               protected void Insert(string str)
-               {
-                       if (!selectionIsEmpty)
-                               this.DeleteChar ();
-                       if (_multiline) {
-                               string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray();
-                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]);
-                               CurrentColumn += strLines[0].Length;
-                               for (int i = 1; i < strLines.Length; i++) {
-                                       InsertLineBreak ();
-                                       lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]);
-                                       CurrentColumn += strLines[i].Length;
-                               }
-                       } else {
-                               lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
-                               CurrentColumn += str.Length;
-                       }
-                       OnTextChanged (this, new TextChangeEventArgs (default));
-               }
-               /// <summary>
-               /// Insert a line break.
-               /// </summary>
-               protected void InsertLineBreak()
-               {
-                       lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn));
-                       lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn);
-                       CurrentLine++;
-                       CurrentColumn = 0;
-                       OnTextChanged (this, new TextChangeEventArgs (default));
-               }
-               bool textMeasureIsUpToDate = false;
-               Size cachedTextSize = default(Size);
-
-               #region GraphicObject overrides
-               public override int measureRawSize(LayoutingType lt)
-               {
-                       if (lines == null)
-                               lines = getLines;
-                       if (!textMeasureIsUpToDate) {
-                               using (Context gr = new Context (IFace.surf)) {
-                                       //Cairo.FontFace cf = gr.GetContextFontFace ();
-
-                                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                                       gr.SetFontSize (Font.Size);
-                                       gr.FontOptions = Interface.FontRenderingOptions;
-                                       gr.Antialias = Interface.Antialias;
-
-                                       fe = gr.FontExtents;
-                                       te = new TextExtents ();
-
-                                       cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Count));
-
-                                       try {
-                                               for (int i = 0; i < lines.Count; i++) {
-                                                       string l = lines[i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
-
-                                                       TextExtents tmp = gr.TextExtents (l);
-
-                                                       if (tmp.XAdvance > te.XAdvance)
-                                                               te = tmp;
-                                               }
-                                               cachedTextSize.Width = (int)Math.Ceiling (te.XAdvance);
-                                               textMeasureIsUpToDate = true;
-                                       } catch {                                                       
-                                               return -1;
-                                       }                                       
-                               }
-                       }
-                       return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width);
-               }
-               protected override void onDraw (Context gr)
-               {
-                       DbgLogger.StartEvent(DbgEvtType.GODraw, this);
-
-                       base.onDraw (gr);
-
-                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                       gr.SetFontSize (Font.Size);
-                       gr.FontOptions = Interface.FontRenderingOptions;
-                       gr.Antialias = Interface.Antialias;
-
-                       gr.Save ();
-                       gr.Translate (xTranslation, 0);
-
-                       rText = new Rectangle(new Size(
-                               measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height)));
-                       rText.Width -= 2 * Margin;
-                       rText.Height -= 2 * Margin;
-
-                       widthRatio = 1f;
-                       heightRatio = 1f;
-
-                       Rectangle cb = ClientRectangle;
-
-                       rText.X = cb.X;
-                       rText.Y = cb.Y;
-
-                       if (horizontalStretch) {
-                               widthRatio = (float)cb.Width / (float)rText.Width;
-                               if (!verticalStretch)
-                                       heightRatio = widthRatio;
-                       }
-
-                       if (verticalStretch) {
-                               heightRatio = (float)cb.Height / (float)rText.Height;
-                               if (!horizontalStretch)
-                                       widthRatio = heightRatio;
-                       }
-
-                       rText.Width = (int)(widthRatio * (float)rText.Width);
-                       rText.Height = (int)(heightRatio * (float)rText.Height);
-
-                       switch (TextAlignment)
-                       {
-                       case Alignment.TopLeft:     //ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Y;
-                               break;
-                       case Alignment.Top:   //ok
-                               rText.Y = cb.Y;
-                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                               break;
-                       case Alignment.TopRight:    //ok
-                               rText.Y = cb.Y;
-                               rText.X = cb.Right - rText.Width;
-                               break;
-                       case Alignment.Left://ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               break;
-                       case Alignment.Right://ok
-                               rText.X = cb.X + cb.Width - rText.Width;
-                               rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               break;
-                       case Alignment.Bottom://ok
-                               rText.X = cb.Width / 2 - rText.Width / 2;
-                               rText.Y = cb.Height - rText.Height;
-                               break;
-                       case Alignment.BottomLeft://ok
-                               rText.X = cb.X;
-                               rText.Y = cb.Bottom - rText.Height;
-                               break;
-                       case Alignment.BottomRight://ok
-                               rText.Y = cb.Bottom - rText.Height;
-                               rText.X = cb.Right - rText.Width;
-                               break;
-                       case Alignment.Center://ok
-                               rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                               //rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                               rText.Y = cb.Y + (int)Math.Floor((double)cb.Height / 2.0 - (double)rText.Height / 2.0);
-                               break;
-                       }
-
-                       //gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0);
-                       fe = gr.FontExtents;
-
-                       #region draw text cursor
-                       if (HasFocus && Selectable)
-                       {
-                               if (mouseLocalPos >= 0)
-                               {
-                                       computeTextCursor(gr);
-
-                                       if (SelectionInProgress)
-                                       {
-                                               if (SelBegin < 0){
-                                                       SelBegin = new Point(CurrentColumn, CurrentLine);
-                                                       SelStartCursorPos = textCursorPos;
-                                                       SelRelease = -1;
-                                               }else{
-                                                       SelRelease = new Point(CurrentColumn, CurrentLine);
-                                                       if (SelRelease == SelBegin)
-                                                               SelRelease = -1;
-                                                       else
-                                                               SelEndCursorPos = textCursorPos;
-                                               }
-                                       }else
-                                               computeTextCursorPosition(gr);
-                               }else
-                                       computeTextCursorPosition(gr);
-
-                               Foreground.SetAsSource (IFace, gr);
-                               gr.LineWidth = 1.0;
-                               gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * (fe.Ascent+fe.Descent));
-                               gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * (fe.Ascent+fe.Descent));
-                               gr.Stroke();
-                       }
-                       #endregion
-
-                       //****** debug selection *************
-//                     if (SelRelease >= 0) {
-//                             new SolidColor(Color.DarkGreen).SetAsSource(gr);
-//                             Rectangle R = new Rectangle (
-//                                                  rText.X + (int)SelEndCursorPos - 3,
-//                                                  rText.Y + (int)(SelRelease.Y * (fe.Ascent+fe.Descent)),
-//                                                  6,
-//                                                  (int)(fe.Ascent+fe.Descent));
-//                             gr.Rectangle (R);
-//                             gr.Fill ();
-//                     }
-//                     if (SelBegin >= 0) {
-//                             new SolidColor(Color.DarkRed).SetAsSource(gr);
-//                             Rectangle R = new Rectangle (
-//                                     rText.X + (int)SelStartCursorPos - 3,
-//                                     rText.Y + (int)(SelBegin.Y * (fe.Ascent+fe.Descent)),
-//                                     6,
-//                                     (int)(fe.Ascent+fe.Descent));
-//                             gr.Rectangle (R);
-//                             gr.Fill ();
-//                     }
-                       //*******************
-
-                       for (int i = 0; i < lines.Count; i++) {
-                               string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
-                               int lineLength = (int)gr.TextExtents (l).XAdvance;
-                               Rectangle lineRect = new Rectangle (
-                                       rText.X,
-                                       rText.Y + i * (int)(fe.Ascent+fe.Descent),
-                                       lineLength,
-                                       (int)(fe.Ascent+fe.Descent));
-
-//                             if (TextAlignment == Alignment.Center ||
-//                                     TextAlignment == Alignment.Top ||
-//                                     TextAlignment == Alignment.Bottom)
-//                                     lineRect.X += (rText.Width - lineLength) / 2;
-//                             else if (TextAlignment == Alignment.Right ||
-//                                     TextAlignment == Alignment.TopRight ||
-//                                     TextAlignment == Alignment.BottomRight)
-//                                     lineRect.X += (rText.Width - lineLength);
-                               if (string.IsNullOrWhiteSpace (l))
-                                       continue;
-
-                               Foreground.SetAsSource (IFace, gr);
-                               gr.MoveTo (lineRect.X,(double)rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i) ;
-
-                gr.ShowText (l);
-                               gr.Fill ();
-
-                               if (Selectable) {
-                                       if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
-                                               gr.SetSource (selBackground);
-
-                                               Rectangle selRect = lineRect;
-
-                                               int cpStart = (int)SelStartCursorPos,
-                                               cpEnd = (int)SelEndCursorPos;
-
-                                               if (SelBegin.Y > SelRelease.Y) {
-                                                       cpStart = cpEnd;
-                                                       cpEnd = (int)SelStartCursorPos;
-                                               }
-
-                                               if (i == selectionStart.Y) {
-                                                       selRect.Width -= cpStart;
-                                                       selRect.Left += cpStart;
-                                               }
-                                               if (i == selectionEnd.Y)
-                                                       selRect.Width -= (lineLength - cpEnd);
-
-                                               gr.Rectangle (selRect);
-                                               gr.FillPreserve ();
-                                               gr.Save ();
-                                               gr.Clip ();
-                                               gr.SetSource (SelectionForeground);
-                                               gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i);
-                                               gr.ShowText (l);
-                                               gr.Fill ();
-                                               gr.Restore ();
-                                       }
-                               }
-                       }
-
-                       gr.Restore ();
-                       DbgLogger.EndEvent (DbgEvtType.GODraw);
-               }
-               #endregion
-
-               #region Mouse handling
-               void updatemouseLocalPos(Point mpos){
-                       mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
-                       mouseLocalPos.X -= xTranslation;
-                       if (mouseLocalPos.X < 0)
-                               mouseLocalPos.X = 0;
-                       if (mouseLocalPos.Y < 0)
-                               mouseLocalPos.Y = 0;
-               }
-               protected override void onFocused (object sender, EventArgs e)
-               {
-                       base.onFocused (sender, e);
-
-                       if (!_selectable)
-                               return;
-                       SelBegin = new Point(0,0);
-                       SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
-                       RegisterForRedraw ();
-               }
-               protected override void onUnfocused (object sender, EventArgs e)
-               {
-                       base.onUnfocused (sender, e);
-
-                       SelBegin = -1;
-                       SelRelease = -1;
-                       RegisterForRedraw ();
-               }
-               public override void onMouseMove (object sender, MouseMoveEventArgs e)
-               {
-                       base.onMouseMove (sender, e);
-
-                       if (!(SelectionInProgress && HasFocus && _selectable))
-                               return;
-
-                       updatemouseLocalPos (e.Position);
-
-                       RegisterForRedraw();
-               }
-               public override void onMouseDown (object sender, MouseButtonEventArgs e)
-               {
-                       if (HasFocus) {
-                               if (_selectable) {
-                                       updatemouseLocalPos (e.Position);
-                                       SelBegin = -1;
-                                       SelRelease = -1;
-                                       SelectionInProgress = true;
-                                       RegisterForRedraw ();//TODO:should put it in properties
-                               }
-                       }
-
-                       //done at the end to set 'hasFocus' value after testing it
-                       base.onMouseDown (sender, e);
-               }
-               public override void onMouseUp (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseUp (sender, e);
-                       if (!(HasFocus || _selectable))
-                               return;
-                       if (!SelectionInProgress)
-                               return;
-
-                       updatemouseLocalPos (e.Position);
-                       SelectionInProgress = false;
-                       RegisterForRedraw ();
-               }
-               public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e)
-               {
-                       base.onMouseDoubleClick (sender, e);
-                       if (!(this.HasFocus || _selectable))
-                               return;
-                       
-                       GotoWordStart ();
-                       SelBegin = CurrentPosition;
-                       GotoWordEnd ();
-                       SelRelease = CurrentPosition;
-                       SelectionInProgress = false;
-                       RegisterForRedraw ();
-               }
-               #endregion
-
-               /// <summary>
-               /// Update Current Column, line and TextCursorPos
-               /// from mouseLocalPos
-               /// </summary>
-               void computeTextCursor(Context gr)
-               {
-                       TextExtents te;
-
-                       double cPos = 0f;
-
-                       CurrentLine = (int)(mouseLocalPos.Y / (fe.Ascent+fe.Descent));
-
-                       //fix cu
-                       if (CurrentLine >= lines.Count)
-                               CurrentLine = lines.Count - 1;
-
-                       switch (TextAlignment) {
-                       case Alignment.Center:
-                       case Alignment.Top:
-                       case Alignment.Bottom:
-                               cPos+= ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width/2.0;
-                               break;
-                       case Alignment.Right:
-                       case Alignment.TopRight:
-                       case Alignment.BottomRight:
-                               cPos += ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width;
-                               break;
-                       }
-
-                       for (int i = 0; i < lines[CurrentLine].Length; i++)
-                       {
-                               string c = lines [CurrentLine].Substring (i, 1);
-                               if (c == "\t")
-                                       c = new string (' ', Interface.TAB_SIZE);
-
-                               te = gr.TextExtents(c);
-
-                               double halfWidth = te.XAdvance / 2;
-
-                               if (mouseLocalPos.X <= cPos + halfWidth)
-                               {
-                                       CurrentColumn = i;
-                                       textCursorPos = cPos;
-                                       mouseLocalPos = -1;
-                                       return;
-                               }
-
-                               cPos += te.XAdvance;
-                       }
-                       CurrentColumn = lines[CurrentLine].Length;
-                       textCursorPos = cPos;
-
-                       //reset mouseLocalPos
-                       mouseLocalPos = -1;
-               }
-               /// <summary> Computes offsets in cairo units </summary>
-               void computeTextCursorPosition(Context gr)
-               {
-                       if (SelBegin >= 0)
-                               SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
-                       if (SelRelease >= 0)
-                               SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
-                       textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
-               }
-               /// <summary> Compute x offset in cairo unit from text position </summary>
-               double GetXFromTextPointer(Context gr, Point pos)
-               {
-                       try {
-                               string l = lines [pos.Y].Substring (0, pos.X).
-                                       Replace ("\t", new String (' ', Interface.TAB_SIZE));
-                               return gr.TextExtents (l).XAdvance;
-                       } catch{
-                               return -1;
-                       }
-               }
-    }
-}
diff --git a/Crow/src/Widgets/OldTextBox.cs b/Crow/src/Widgets/OldTextBox.cs
deleted file mode 100644 (file)
index 01ef5ac..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright (c) 2013-2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-using Glfw;
-using System;
-
-namespace Crow
-{
-       [Obsolete]
-       public class OldTextBox : OldLabel
-    {
-               #region CTOR
-               protected OldTextBox() {}
-               public OldTextBox(Interface iface, string style = null) : base (iface, style) { }
-               #endregion
-
-               #region GraphicObject overrides
-               [XmlIgnore]public override bool HasFocus   //trigger update when lost focus to errase text beam
-        {
-            get => base.HasFocus;
-            set {
-                               if (base.HasFocus == value)
-                                       return;
-                base.HasFocus = value;
-                RegisterForRedraw();
-            }
-        }
-
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-               }
-               #endregion
-                       
-        #region Keyboard handling
-               public override void onKeyDown (object sender, KeyEventArgs e)
-               {
-                       Key key = e.Key;
-
-                       switch (key)
-                       {
-                       case Key.Backspace:
-                               if (CurrentPosition == 0)
-                                       return;
-                               DeleteChar();
-                               break;
-                       case Key.Delete:
-                               if (selectionIsEmpty) {
-                                       if (!MoveRight ())
-                                               return;
-                               }else if (IFace.Shift)
-                                       IFace.Clipboard = SelectedText;
-                               DeleteChar ();
-                               break;
-                       case Key.KeypadEnter:
-                       case Key.Enter:
-                               if (!selectionIsEmpty)
-                                       DeleteChar ();
-                               if (Multiline)
-                                       InsertLineBreak ();
-                               else
-                                       OnTextChanged(this,new TextChangeEventArgs(default));
-                               break;
-                       case Key.Escape:
-                               Text = "";
-                               CurrentColumn = 0;
-                               SelRelease = -1;
-                               break;
-                       case Key.Home:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = new Point (CurrentColumn, CurrentLine);
-                                       if (IFace.Ctrl)
-                                               CurrentLine = 0;
-                                       CurrentColumn = 0;
-                                       SelRelease = new Point (CurrentColumn, CurrentLine);
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (IFace.Ctrl)
-                                       CurrentLine = 0;
-                               CurrentColumn = 0;
-                               break;
-                       case Key.End:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       if (IFace.Ctrl)
-                                               CurrentLine = int.MaxValue;
-                                       CurrentColumn = int.MaxValue;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (IFace.Ctrl)
-                                       CurrentLine = int.MaxValue;
-                               CurrentColumn = int.MaxValue;
-                               break;
-                       case Key.Insert:
-                               if (IFace.Shift)
-                                       this.Insert (IFace.Clipboard);
-                               else if (IFace.Ctrl && !selectionIsEmpty)
-                                       IFace.Clipboard = this.SelectedText;
-                               break;
-                       case Key.Left:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = new Point(CurrentColumn, CurrentLine);
-                                       if (IFace.Ctrl)
-                                               GotoWordStart ();
-                                       else if (!MoveLeft ())
-                                               return;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (IFace.Ctrl)
-                                       GotoWordStart ();
-                               else
-                                       MoveLeft();
-                               break;
-                       case Key.Right:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       if (IFace.Ctrl)
-                                               GotoWordEnd ();
-                                       else if (!MoveRight ())
-                                               return;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               if (IFace.Ctrl)
-                                       GotoWordEnd ();
-                               else
-                                       MoveRight ();
-                               break;
-                       case Key.Up:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       CurrentLine--;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               CurrentLine--;
-                               break;
-                       case Key.Down:
-                               if (IFace.Shift) {
-                                       if (selectionIsEmpty)
-                                               SelBegin = CurrentPosition;
-                                       CurrentLine++;
-                                       SelRelease = CurrentPosition;
-                                       break;
-                               }
-                               SelRelease = -1;
-                               CurrentLine++;                          
-                               break;
-                       case Key.Tab:
-                               this.Insert ("\t");
-                               break;
-                       default:
-                               break;
-                       }
-                       e.Handled = true;
-                       base.onKeyDown (sender, e);
-                       RegisterForGraphicUpdate ();
-               }
-               public override void onKeyPress (object sender, KeyPressEventArgs e)
-               {
-                       base.onKeyPress (sender, e);
-
-                       this.Insert (e.KeyChar.ToString());
-
-                       SelRelease = -1;
-                       SelBegin = new Point(CurrentColumn, SelBegin.Y);
-
-                       RegisterForGraphicUpdate();
-               }
-        #endregion
-       } 
-}
index b00bb2113410b155457a0918dbca056fe1693c0f..d30c7bd672ce50acf678748c1f29b0c5ad4c922e 100644 (file)
@@ -4,7 +4,11 @@
 
 using System;
 using System.ComponentModel;
+#if VKVG
+using vkvg;
+#else
 using Crow.Cairo;
+#endif
 
 namespace Crow {
        public class ScrollingStack : GenericStack {
diff --git a/Crow/src/Widgets/TestCairoPatch.cs b/Crow/src/Widgets/TestCairoPatch.cs
deleted file mode 100644 (file)
index ba59895..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) 2013-2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-
-namespace Crow
-{
-       public class TestCairoPatch : Widget
-       {
-               void computeControlPoints (
-                       double xc, double yc,
-                       double x1, double y1,
-                       out double x2, out double y2,
-                       out double x3, out double y3,
-                       double x4, double y4){
-                       double ax = x1 - xc;
-                       double ay = y1 - yc;
-                       double bx = x4 - xc;
-                       double byy = y4 - yc;
-                       double q1 = ax * ax + ay * ay;
-                       double q2 = q1 + ax * bx + ay * byy;
-                       double k2 = 4.0/3.0 * (Math.Sqrt(2.0 * q1 * q2) - q2) / (ax * byy - ay * bx);
-
-
-                       x2 = xc + ax - k2 * ay;
-                       y2 = yc + ay + k2 * ax;
-                       x3 = xc + bx + k2 * byy;
-                       y3 = yc + byy - k2 * bx;
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       double radius = Math.Min (ClientRectangle.Width, ClientRectangle.Height) / 2;
-
-                       double pi3 = Math.PI / 3.0;
-
-                       MeshPattern mp = new MeshPattern ();
-
-                       double x1 = radius,y1 = 0,
-                       x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0,
-                       xc = radius,yc = radius;
-
-                       double dx = Math.Sin (pi3) * radius;
-                       double dy = Math.Cos (pi3) * radius;
-
-                       mp.BeginPatch ();
-                       mp.MoveTo (xc, yc);
-                       mp.LineTo (x1, y1);
-                       x4 = xc + dx;
-                       y4 = yc - dy;
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (0, 1, 1, 1);
-                       mp.SetCornerColorRGB (1, 1, 0, 0);
-                       mp.SetCornerColorRGB (2, 1, 1, 0);
-
-                       x1 = x4;
-                       y1 = y4;
-                       y4 = yc + dy;
-
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (3, 0, 1, 0);
-                       mp.EndPatch ();
-
-                       x1 = x4;
-                       y1 = y4;
-                       x4 = xc;
-                       y4 = yc * 2.0;
-
-                       mp.BeginPatch ();
-                       mp.MoveTo (xc, yc);
-                       mp.LineTo (x1, y1);
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (0, 1, 1, 1);
-                       mp.SetCornerColorRGB (1, 0, 1, 0);
-                       mp.SetCornerColorRGB (2, 0, 1, 1);
-
-                       x1 = x4;
-                       y1 = y4;
-                       x4 = xc-dx;
-                       y4 = yc+dy;
-
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (3, 0, 0, 1);
-                       mp.EndPatch ();
-
-                       x1 = x4;
-                       y1 = y4;
-                       y4 = yc - dy;
-
-                       mp.BeginPatch ();
-                       mp.MoveTo (xc, yc);
-                       mp.LineTo (x1, y1);
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (0, 1, 1, 1);
-                       mp.SetCornerColorRGB (1, 0, 0, 1);
-                       mp.SetCornerColorRGB (2, 1, 0, 1);
-
-                       x1 = x4;
-                       y1 = y4;
-                       x4 = radius;
-                       y4 = 0;
-
-                       computeControlPoints (xc, yc, x1, y1, out x2, out y2, out x3, out y3, x4, y4);
-                       mp.CurveTo (x2, y2, x3, y3, x4, y4);
-
-                       mp.SetCornerColorRGB (3, 1, 0, 0);
-                       mp.EndPatch ();
-
-                       gr.SetSource (mp);
-                       gr.Paint ();
-               }
-       }
-}
-
diff --git a/Crow/src/Widgets/TextRun.cs b/Crow/src/Widgets/TextRun.cs
deleted file mode 100644 (file)
index 9efa5cb..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright (c) 2013-2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Linq;
-using System.Text.RegularExpressions;
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-
-namespace Crow
-{
-       [DesignIgnore]
-       public class TextRun : Widget
-       {
-               #region CTOR
-               protected TextRun () {}
-               public TextRun (Interface iface, string style = null) : base (iface, style) { }
-               #endregion
-
-               #region private and protected fields
-               protected string _text = "label";
-               Alignment _textAlignment = Alignment.Left;
-               bool horizontalStretch = false;
-               bool verticalStretch = false;
-               bool _multiline;
-               bool wordWrap;
-               protected Rectangle rText;
-               protected float widthRatio = 1f;
-               protected float heightRatio = 1f;
-               protected FontExtents fe;
-               protected TextExtents te;
-               #endregion
-               
-               [DefaultValue (Alignment.Left)]
-               public Alignment TextAlignment {
-                       get { return _textAlignment; }
-                       set { _textAlignment = value; }
-               }
-               
-               [DefaultValue (false)]
-               public virtual bool HorizontalStretch {
-                       get { return horizontalStretch; }
-                       set {
-                               if (horizontalStretch == value)
-                                       return;
-                               horizontalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChangedAuto (horizontalStretch);
-                       }
-               }
-               
-               [DefaultValue (false)]
-               public virtual bool VerticalStretch {
-                       get { return verticalStretch; }
-                       set {
-                               if (verticalStretch == value)
-                                       return;
-                               verticalStretch = value;
-                               RegisterForRedraw ();
-                               NotifyValueChangedAuto (verticalStretch);
-                       }
-               }
-               
-               [DefaultValue ("label")]
-               public string Text {
-                       get {
-                               return lines == null ?
-                                       _text : lines.Aggregate ((i, j) => i + Interface.LineBreak + j);
-                       }
-                       set {
-                               if (_text == value)
-                                       return;
-
-                               RegisterForGraphicUpdate ();
-
-                               _text = value;
-
-                               if (string.IsNullOrEmpty (_text))
-                                       _text = "";
-
-                               lines = getLines;
-                       }
-               }
-               
-               [DefaultValue (false)]
-               public bool Multiline {
-                       get { return _multiline; }
-                       set {
-                               _multiline = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               
-               [DefaultValue (false)]
-               public bool WordWrap {
-                       get {
-                               return wordWrap;
-                       }
-                       set {
-                               if (wordWrap == value)
-                                       return;
-                               wordWrap = value;
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-
-               List<string> lines;
-               List<string> getLines {
-                       get {
-                               return _multiline ?
-                                       Regex.Split (_text, "\r\n|\r|\n").ToList () :
-                                       new List<string> (new string [] { _text });
-                       }
-               }
-
-               #region GraphicObject overrides
-               public override int measureRawSize (LayoutingType lt)
-               {
-                       if (lines == null)
-                               lines = getLines;
-                               
-                       using (Context gr = new Context (IFace.surf)) {
-                               //Cairo.FontFace cf = gr.GetContextFontFace ();
-
-                               gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                               gr.SetFontSize (Font.Size);
-
-
-                               fe = gr.FontExtents;
-                               te = new TextExtents ();
-
-                               if (lt == LayoutingType.Height) {
-                                       int lc = lines.Count;
-                                       //ensure minimal height = text line height
-                                       if (lc == 0)
-                                               lc = 1;
-
-                                       return (int)(fe.Height * lc) + Margin * 2;
-                               }
-
-                               foreach (string s in lines) {
-                                       string l = s.Replace("\t", new String (' ', Interface.TAB_SIZE));
-                                       TextExtents tmp = gr.TextExtents (l);
-                                       if (tmp.XAdvance > te.XAdvance)
-                                               te = tmp;
-                               }
-                               return (int)Math.Ceiling (te.XAdvance) + Margin * 2;
-                       }
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
-                       gr.SetFontSize (Font.Size);
-                       gr.FontOptions = Interface.FontRenderingOptions;
-                       gr.Antialias = Interface.Antialias;
-
-                       rText = new Rectangle (new Size (
-                               measureRawSize (LayoutingType.Width), measureRawSize (LayoutingType.Height)));
-                       rText.Width -= 2 * Margin;
-                       rText.Height -= 2 * Margin;
-
-                       widthRatio = 1f;
-                       heightRatio = 1f;
-
-                       Rectangle cb = ClientRectangle;
-
-                       //ignore text alignment if size to content = true
-                       //or if text size is larger than client bounds
-                       if (Width < 0 || Height < 0 || rText.Width > cb.Width) {
-                               rText.X = cb.X;
-                               rText.Y = cb.Y;
-                       } else {
-                               if (horizontalStretch) {
-                                       widthRatio = (float)cb.Width / rText.Width;
-                                       if (!verticalStretch)
-                                               heightRatio = widthRatio;
-                               }
-                               if (verticalStretch) {
-                                       heightRatio = (float)cb.Height / rText.Height;
-                                       if (!horizontalStretch)
-                                               widthRatio = heightRatio;
-                               }
-
-                               rText.Width = (int)(widthRatio * cb.Width);
-                               rText.Height = (int)(heightRatio * cb.Height);
-
-                               switch (TextAlignment) {
-                               case Alignment.TopLeft:     //ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Y;
-                                       break;
-                               case Alignment.Top:   //ok                                              
-                                       rText.Y = cb.Y;
-                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                                       break;
-                               case Alignment.TopRight:    //ok
-                                       rText.Y = cb.Y;
-                                       rText.X = cb.Right - rText.Width;
-                                       break;
-                               case Alignment.Left://ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               case Alignment.Right://ok
-                                       rText.X = cb.X + cb.Width - rText.Width;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               case Alignment.Bottom://ok
-                                       rText.X = cb.Width / 2 - rText.Width / 2;
-                                       rText.Y = cb.Height - rText.Height;
-                                       break;
-                               case Alignment.BottomLeft://ok
-                                       rText.X = cb.X;
-                                       rText.Y = cb.Bottom - rText.Height;
-                                       break;
-                               case Alignment.BottomRight://ok
-                                       rText.Y = cb.Bottom - rText.Height;
-                                       rText.X = cb.Right - rText.Width;
-                                       break;
-                               case Alignment.Center://ok
-                                       rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
-                                       rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
-                                       break;
-                               }
-                       }
-
-                       gr.FontMatrix = new Matrix (widthRatio * Font.Size, 0, 0, heightRatio * Font.Size, 0, 0);
-
-
-                       int curLineCount = 0;
-                       for (int i = 0; i < lines.Count; i++) {
-                               string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
-                               List<string> wl = new List<string> ();
-                               int lineLength = (int)gr.TextExtents (l).XAdvance;
-
-                               if (wordWrap && lineLength > cb.Width) {
-                                       string tmpLine = "";
-                                       int curChar = 0;
-                                       while (curChar < l.Length) {
-                                               tmpLine += l [curChar];
-                                               if ((int)gr.TextExtents (tmpLine).XAdvance > cb.Width) {
-                                                       tmpLine = tmpLine.Remove (tmpLine.Length - 1);
-                                                       wl.Add (tmpLine);
-                                                       tmpLine = "";
-                                                       continue;
-                                               }
-                                               curChar++;
-                                       }
-                                       wl.Add (tmpLine);
-                               } else
-                                       wl.Add (l);
-
-                               foreach (string ll in wl) {
-                                       lineLength = (int)gr.TextExtents (ll).XAdvance;
-
-
-                                       if (string.IsNullOrWhiteSpace (ll)) {
-                                               curLineCount++;
-                                               continue;
-                                       }
-
-                                       Foreground.SetAsSource (IFace, gr);
-                                       gr.MoveTo (rText.X, rText.Y + fe.Ascent + fe.Height * curLineCount);
-
-                                       gr.ShowText (ll);
-                                       gr.Fill ();
-
-                                       curLineCount++;
-                               }
-                       }
-               }
-               #endregion
-       }
-}
diff --git a/Crow/src/Widgets/Trend.cs b/Crow/src/Widgets/Trend.cs
deleted file mode 100644 (file)
index 808cd76..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2013-2020  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-
-using System.Collections.Generic;
-using System.ComponentModel;
-#if VKVG
-using vkvg;
-#else
-using Crow.Cairo;
-#endif
-
-namespace Crow
-{
-       public class Trend : Widget
-       {
-               #region private fields
-               double minValue, maxValue, lowThreshold, highThreshold;
-               Fill lowThresholdFill, highThresholdFill;
-               int nbValues;
-               List<double> values = new List<double>();
-               #endregion
-
-               #region CTOR
-               protected Trend () {}
-               public Trend (Interface iface, string style = null) : base (iface, style) { }
-               #endregion
-
-               public virtual void AddValue (double _value)
-               {
-                       values.Add (_value);
-                       while (values.Count > nbValues)
-                               values.RemoveAt (0);
-                       RegisterForRedraw ();
-               }
-
-               [XmlIgnore]public virtual int NewValue {
-                       set {
-                               AddValue (value);
-                       }
-               }
-               [DefaultValue(400)]
-               public virtual int NbValues {
-                       get { return nbValues; }
-                       set {
-                               if (nbValues == value)
-                                       return;
-
-                               nbValues = value;
-                               NotifyValueChangedAuto (minValue);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(0.0)]
-               public virtual double Minimum {
-                       get { return minValue; }
-                       set {
-                               if (minValue == value)
-                                       return;
-
-                               minValue = value;
-                               NotifyValueChangedAuto (minValue);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(100.0)]
-               public virtual double Maximum
-               {
-                       get { return maxValue; }
-                       set {
-                               if (maxValue == value)
-                                       return;
-
-                               maxValue = value;
-                               NotifyValueChangedAuto (maxValue);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue(1.0)]
-               public virtual double LowThreshold {
-                       get { return lowThreshold; }
-                       set {
-                               if (lowThreshold == value)
-                                       return;
-                               lowThreshold = value;
-                               NotifyValueChangedAuto (lowThreshold);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [DefaultValue(80.0)]
-               public virtual double HighThreshold {
-                       get { return highThreshold; }
-                       set {
-                               if (highThreshold == value)
-                                       return;
-                               highThreshold = value;
-                               NotifyValueChangedAuto (highThreshold);
-                               RegisterForGraphicUpdate ();
-                       }
-               }
-               [DefaultValue("DarkRed")]
-               public virtual Fill LowThresholdFill {
-                       get { return lowThresholdFill; }
-                       set {
-                               if (lowThresholdFill == value)
-                                       return;
-                               lowThresholdFill = value;
-                               NotifyValueChangedAuto (lowThresholdFill);
-                               RegisterForRedraw ();
-                       }
-               }
-               [DefaultValue("DarkGreen")]
-               public virtual Fill HighThresholdFill {
-                       get { return highThresholdFill; }
-                       set {
-                               if (highThresholdFill == value)
-                                       return;
-                               highThresholdFill = value;
-                               NotifyValueChangedAuto (highThresholdFill);
-                               RegisterForRedraw ();
-                       }
-               }
-               protected override void onDraw (Context gr)
-               {
-                       base.onDraw (gr);
-
-                       if (values.Count == 0)
-                               return;
-                       Rectangle r = ClientRectangle;
-
-                       int i = values.Count -1;
-
-                       double ptrX = (double)r.Right;
-                       double scaleY = (double)r.Height / (Maximum - Minimum);
-                       double stepX = (double)r.Width / (double)(nbValues-1);
-
-                       gr.LineWidth = 1.0;
-                       gr.SetDash (new double[]{ 1.0 },0.0);
-
-
-
-                       LowThresholdFill.SetAsSource (IFace, gr);
-                       gr.MoveTo (r.Left, r.Bottom - LowThreshold * scaleY);
-                       gr.LineTo (r.Right, r.Bottom - LowThreshold * scaleY);
-//                     gr.Rectangle (r.Left, r.Bottom - LowThreshold * scaleY, r.Width, LowThreshold * scaleY);
-                       gr.Stroke();
-
-                       HighThresholdFill.SetAsSource (IFace, gr);
-                       gr.MoveTo (r.Left, (Maximum - HighThreshold) * scaleY);
-                       gr.LineTo (r.Right, (Maximum - HighThreshold) * scaleY);
-//                     gr.Rectangle (r.Left, r.Top, r.Width, (Maximum - HighThreshold) * scaleY);
-                       gr.Stroke();
-
-                       gr.MoveTo (ptrX, values [i] * scaleY);
-
-                       Foreground.SetAsSource (IFace, gr);
-                       gr.SetDash (new double[]{ }, 0.0);
-
-                       while (i >= 0) {
-                                       gr.LineTo (ptrX, r.Bottom - values [i] * scaleY);
-                               ptrX -= stepX;
-                               i--;
-                       }
-                       gr.Stroke ();
-               }
-       }
-}
-
index 5a60e237017c5d15a701316a68cc0d3ea8e7d519..8c3b82a224617dc151fe3ad64e6ce0ae24f03cfd 100644 (file)
@@ -122,7 +122,11 @@ namespace Crow
                        parentElem.AppendChild (xe);
                }
                public Surface CreateIcon (int dragIconSize = 32) {
+#if VKVG                       
+                       Surface di = new Surface (IFace.vkvgDevice, dragIconSize, dragIconSize);
+#else
                        ImageSurface di = new ImageSurface (Format.Argb32, dragIconSize, dragIconSize);
+#endif
                        using (Context ctx = new Context (di)) {
                                double div = Math.Max (LastPaintedSlot.Width, LastPaintedSlot.Height);
                                double s = (double)dragIconSize / div;
@@ -1890,10 +1894,16 @@ namespace Crow
                #endregion
 
                protected void setFontForContext (Context gr) {
+#if VKVG
+                       gr.FontFace = Font.Name;
+                       gr.FontSize = (uint)Font.Size;
+
+#else
                        gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
                        gr.SetFontSize (Font.Size);
                        gr.FontOptions = Interface.FontRenderingOptions;
                        gr.Antialias = Interface.Antialias;
+#endif
                }
 
                #region Rendering
@@ -1923,7 +1933,11 @@ namespace Crow
                        else if (LastPaintedSlot.Width != Slot.Width || LastPaintedSlot.Height != Slot.Height)
                                bmp.SetSize (Slot.Width, Slot.Height);*/
                        bmp?.Dispose ();
+#if (VKVG)
+                       bmp = new Surface (IFace.vkvgDevice, Slot.Width, Slot.Height);
+#else
                        bmp = IFace.surf.CreateSimilar (Content.ColorAlpha, Slot.Width, Slot.Height);
+#endif
                        //bmp = new ImageSurface(Format.Argb32, Slot.Width, Slot.Height);
 
                        using (Context gr = new Context (bmp)) {
index 27a3c0c81451de6907cb018731d72e7b90c8ce2c..8ef0496052d36311b689d8ef079a420e94c4a2ce 100644 (file)
@@ -13,6 +13,6 @@
                <CrowDebugStatsEnabled>true</CrowDebugStatsEnabled>
                <CrowDesignModeEnabled>true</CrowDesignModeEnabled>
                <CrowVkvgBackend>true</CrowVkvgBackend>
-               <GlfwSharpVersion>0.2.11-beta</GlfwSharpVersion>
+               <GlfwSharpVersion>0.2.12-beta</GlfwSharpVersion>
        </PropertyGroup>
 </Project>
index a19eee51e72bafcbe55e2bae4b7388963a189914..09f5db36ce016b47cce4fc84e72433037e51da0d 100644 (file)
@@ -100,6 +100,7 @@ namespace Crow
                                }
 
                                gr.LineWidth = 1;
+                               
                                gr.SetDash (new double [] { 1.0, 3.0 }, 0);
 
                                Rectangle cb = ClientRectangle;
index ea8b31f3783f8df11857c34d1eca247d9c7b815e..42dc1ad5db8b6fbf215782369e7a620965ff1405 100644 (file)
                <EnableDefaultNoneItems>false</EnableDefaultNoneItems>
                <SamplesDir>$(MSBuildThisFileDirectory)\</SamplesDir>
                <AppConfig>$(SolutionDir)Crow\App.config</AppConfig>
+
+               <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
+
        </PropertyGroup>
-       
+
+       <PropertyGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
+               <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
+       </PropertyGroup>
+
        <ItemGroup>
                <ProjectReference Include="$(SolutionDir)Crow\Crow.csproj" />
        </ItemGroup>
index fe05d1e284d65a39ae634b2f9a054beac5440028..0baeb4b83c473698c936278289d16c3a31a5a086 100644 (file)
@@ -1,2 +1,2 @@
 <?xml version="1.0"?>
-<Label Text="Hello World"/>
\ No newline at end of file
+<Widget Background="Blue"/>
\ No newline at end of file
index 686afaed9b4914b905b6c55e47dd5bf9302cf87b..553439b4169a6bd307baff9376d29d7f592e075c 100644 (file)
@@ -6,7 +6,11 @@ using System;
 using Glfw;
 using Crow.Text;
 using System.Collections.Generic;
+#if VKVG
+using vkvg;
+#else
 using Crow.Cairo;
+#endif
 using System.Threading.Tasks;
 using System.Linq;
 using System.Diagnostics.CodeAnalysis;
index 8d7718ed3374d65b3fe0c184c84bd20b6059c0c1..2e307c2bffb29cdff32b9d72d4282478ecaf647b 100644 (file)
@@ -10,6 +10,12 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Threading;
 
+#if VKVG
+using vkvg;
+#else
+using Crow.Cairo;
+#endif
+
 namespace Samples
 {
        public class SampleBase : Interface
@@ -376,7 +382,7 @@ namespace Samples
                        initCommands();
                        base.OnInitialized();
                }
-               protected override void processDrawing(Crow.Cairo.Context ctx)
+               protected override void processDrawing(Context ctx)
                {
                        base.processDrawing(ctx);
                }