aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2021-08-02 13:13:21 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2021-08-02 13:13:21 +0200
commit85190e474cae0a87e29755c156140cd29c85cbb5 (patch)
tree5d13272e927994c5ff3f1fc48999254c90007de9
parent61d58bc83b6e4af1a7e98e30c3fbdaf31388026a (diff)
merge vkvg2 into devel
-rw-r--r--Crow/Crow.csproj23
-rw-r--r--Crow/src/Cairo/CairoHelpers.cs56
-rw-r--r--Crow/src/DebugUtils/PerformanceMeasure.cs2
-rw-r--r--Crow/src/ExtensionsMethods.cs12
-rw-r--r--Crow/src/Fill/BmpPicture.cs50
-rw-r--r--Crow/src/Fill/Fill.cs4
-rw-r--r--Crow/src/Fill/Gradient.cs33
-rw-r--r--Crow/src/Fill/Picture.cs34
-rw-r--r--Crow/src/Fill/SolidColor.cs5
-rw-r--r--Crow/src/Fill/SvgPicture.cs62
-rw-r--r--Crow/src/Font.cs3
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Antialias.cs (renamed from Crow/src/Mono.Cairo/Antialias.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Cairo.cs (renamed from Crow/src/Mono.Cairo/Cairo.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/CairoDebug.cs (renamed from Crow/src/Mono.Cairo/CairoDebug.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Content.cs (renamed from Crow/src/Mono.Cairo/Content.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Context.cs (renamed from Crow/src/Mono.Cairo/Context.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/DRMDevice.cs (renamed from Crow/src/Mono.Cairo/DRMDevice.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/DRMSurface.cs (renamed from Crow/src/Mono.Cairo/DRMSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Device.cs (renamed from Crow/src/Mono.Cairo/Device.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/DirectFBSurface.cs (renamed from Crow/src/Mono.Cairo/DirectFBSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Distance.cs (renamed from Crow/src/Mono.Cairo/Distance.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/EGLDevice.cs (renamed from Crow/src/Mono.Cairo/EGLDevice.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Extend.cs (renamed from Crow/src/Mono.Cairo/Extend.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FillRule.cs (renamed from Crow/src/Mono.Cairo/FillRule.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Filter.cs (renamed from Crow/src/Mono.Cairo/Filter.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontExtents.cs (renamed from Crow/src/Mono.Cairo/FontExtents.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontFace.cs (renamed from Crow/src/Mono.Cairo/FontFace.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontOptions.cs (renamed from Crow/src/Mono.Cairo/FontOptions.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontSlant.cs (renamed from Crow/src/Mono.Cairo/FontSlant.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontType.cs (renamed from Crow/src/Mono.Cairo/FontType.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/FontWeight.cs (renamed from Crow/src/Mono.Cairo/FontWeight.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Format.cs (renamed from Crow/src/Mono.Cairo/Format.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/GLSurface.cs (renamed from Crow/src/Mono.Cairo/GLSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/GLXDevice.cs (renamed from Crow/src/Mono.Cairo/GLXDevice.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/GlitzSurface.cs (renamed from Crow/src/Mono.Cairo/GlitzSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Glyph.cs (renamed from Crow/src/Mono.Cairo/Glyph.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Gradient.cs (renamed from Crow/src/Mono.Cairo/Gradient.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/HintMetrics.cs (renamed from Crow/src/Mono.Cairo/HintMetrics.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/HintStyle.cs (renamed from Crow/src/Mono.Cairo/HintStyle.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/ImageSurface.cs (renamed from Crow/src/Mono.Cairo/ImageSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/LineCap.cs (renamed from Crow/src/Mono.Cairo/LineCap.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/LineJoin.cs (renamed from Crow/src/Mono.Cairo/LineJoin.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/LinearGradient.cs (renamed from Crow/src/Mono.Cairo/LinearGradient.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Matrix.cs (renamed from Crow/src/Mono.Cairo/Matrix.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/MeshPattern.cs (renamed from Crow/src/Mono.Cairo/MeshPattern.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/NativeMethods-internal.cs (renamed from Crow/src/Mono.Cairo/NativeMethods-internal.cs)0
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/NativeMethods.cs (renamed from Crow/src/Mono.Cairo/NativeMethods.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Operator.cs (renamed from Crow/src/Mono.Cairo/Operator.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/PSSurface.cs (renamed from Crow/src/Mono.Cairo/PSSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Path.cs (renamed from Crow/src/Mono.Cairo/Path.cs)4
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Pattern.cs (renamed from Crow/src/Mono.Cairo/Pattern.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/PatternType.cs (renamed from Crow/src/Mono.Cairo/PatternType.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/PdfSurface.cs (renamed from Crow/src/Mono.Cairo/PdfSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/RadialGradient.cs (renamed from Crow/src/Mono.Cairo/RadialGradient.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Region.cs (renamed from Crow/src/Mono.Cairo/Region.cs)3
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/ScaledFont.cs (renamed from Crow/src/Mono.Cairo/ScaledFont.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SolidPattern.cs (renamed from Crow/src/Mono.Cairo/SolidPattern.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Status.cs (renamed from Crow/src/Mono.Cairo/Status.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SubpixelOrder.cs (renamed from Crow/src/Mono.Cairo/SubpixelOrder.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Surface.cs (renamed from Crow/src/Mono.Cairo/Surface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SurfacePattern.cs (renamed from Crow/src/Mono.Cairo/SurfacePattern.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SurfaceType.cs (renamed from Crow/src/Mono.Cairo/SurfaceType.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SvgSurface.cs (renamed from Crow/src/Mono.Cairo/SvgSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/SvgVersion.cs (renamed from Crow/src/Mono.Cairo/SvgVersion.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/TextExtents.cs (renamed from Crow/src/Mono.Cairo/TextExtents.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/WGLDevice.cs (renamed from Crow/src/Mono.Cairo/WGLDevice.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/Win32Surface.cs (renamed from Crow/src/Mono.Cairo/Win32Surface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/XcbSurface.cs (renamed from Crow/src/Mono.Cairo/XcbSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/XlibSurface.cs (renamed from Crow/src/Mono.Cairo/XlibSurface.cs)2
-rw-r--r--Crow/src/GraphicBackends/Mono.Cairo/rsvg/SvgHandle.cs (renamed from Crow/src/rsvg/Handle.cs)49
-rw-r--r--Crow/src/GraphicBackends/vkvg/Context.cs386
-rw-r--r--Crow/src/GraphicBackends/vkvg/Device.cs50
-rw-r--r--Crow/src/GraphicBackends/vkvg/Enums.cs143
-rw-r--r--Crow/src/GraphicBackends/vkvg/FontExtents.cs106
-rw-r--r--Crow/src/GraphicBackends/vkvg/Matrix.cs92
-rw-r--r--Crow/src/GraphicBackends/vkvg/NativeMethods.cs275
-rw-r--r--Crow/src/GraphicBackends/vkvg/Pattern.cs92
-rw-r--r--Crow/src/GraphicBackends/vkvg/Surface.cs86
-rw-r--r--Crow/src/GraphicBackends/vkvg/SvgHandle.cs42
-rw-r--r--Crow/src/GraphicBackends/vkvg/TextExtents.cs72
-rw-r--r--Crow/src/GraphicBackends/vkvg/TextRun.cs54
-rw-r--r--Crow/src/GraphicBackends/vkvg/VulkanContext.cs207
-rw-r--r--Crow/src/GraphicBackends/vkvg/tmp/FontOptions.cs74
-rw-r--r--Crow/src/GraphicBackends/vkvg/tmp/Region.cs133
-rw-r--r--Crow/src/Interface.cs103
-rw-r--r--Crow/src/Mono.Cairo0
-rw-r--r--Crow/src/Text/IEditableTextWidget.cs2
-rw-r--r--Crow/src/Widgets/Border.cs12
-rw-r--r--Crow/src/Widgets/CircleMeter.cs5
-rw-r--r--Crow/src/Widgets/ColorSlider.cs5
-rw-r--r--Crow/src/Widgets/DockWindow.cs8
-rw-r--r--Crow/src/Widgets/Expandable.cs2
-rw-r--r--Crow/src/Widgets/Gauge.cs3
-rw-r--r--Crow/src/Widgets/GraduatedSlider.cs2
-rw-r--r--Crow/src/Widgets/Group.cs2
-rw-r--r--Crow/src/Widgets/GroupBase.cs7
-rw-r--r--Crow/src/Widgets/HueSelector.cs29
-rw-r--r--Crow/src/Widgets/Image.cs7
-rw-r--r--Crow/src/Widgets/Label.cs7
-rw-r--r--Crow/src/Widgets/OldLabel.cs846
-rw-r--r--Crow/src/Widgets/OldTextBox.cs186
-rw-r--r--Crow/src/Widgets/PrivateContainer.cs4
-rw-r--r--Crow/src/Widgets/ProgressBar.cs2
-rw-r--r--Crow/src/Widgets/SaturationValueSelector.cs2
-rw-r--r--Crow/src/Widgets/Scroller.cs11
-rw-r--r--Crow/src/Widgets/ScrollingStack.cs2
-rw-r--r--Crow/src/Widgets/Shape.cs8
-rw-r--r--Crow/src/Widgets/Slider.cs2
-rw-r--r--Crow/src/Widgets/TabView.cs2
-rw-r--r--Crow/src/Widgets/Table.cs2
-rw-r--r--Crow/src/Widgets/TableRow copy.cs2
-rw-r--r--Crow/src/Widgets/TableRow.cs2
-rw-r--r--Crow/src/Widgets/TemplatedControl.cs14
-rw-r--r--Crow/src/Widgets/TemplatedGroup.cs2
-rw-r--r--Crow/src/Widgets/TestCairoPatch.cs127
-rw-r--r--Crow/src/Widgets/TextBox.cs7
-rw-r--r--Crow/src/Widgets/TextRun.cs278
-rw-r--r--Crow/src/Widgets/Trend.cs164
-rw-r--r--Crow/src/Widgets/Widget.cs31
-rw-r--r--Crow/src/rsvg/DimensionData.cs24
-rw-r--r--Directory.Build.props6
-rw-r--r--Samples/DebugLogAnalyzer/src/DbgEventWidget.cs2
-rw-r--r--Samples/DebugLogAnalyzer/src/DbgLogViewer.cs2
-rw-r--r--Samples/DebugLogAnalyzer/src/DebugInterface.cs2
-rw-r--r--Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs2
-rw-r--r--Samples/common/src/Editor.cs2
-rw-r--r--Samples/common/src/SampleBase.cs4
-rw-r--r--Samples/common/ui/Interfaces/TemplatedControl/testEnumSelector.crow2
128 files changed, 2225 insertions, 1971 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj
index 972e22f1..e778a55b 100644
--- a/Crow/Crow.csproj
+++ b/Crow/Crow.csproj
@@ -44,13 +44,6 @@
<PackageReference Include="glfw-sharp" Version="$(GlfwSharpVersion)" />
</ItemGroup>
- <PropertyGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
- <DefineConstants>$(DefineConstants);VKVG</DefineConstants>
- </PropertyGroup>
- <ItemGroup Condition=" '$(CrowVkvgBackend)' == 'true'">
- <PackageReference Include="vkvg.net" Version="0.2.2-beta" />
- </ItemGroup>
-
<PropertyGroup Condition=" '$(CrowStbSharp)' == 'true'">
<DefineConstants>$(DefineConstants);STB_SHARP</DefineConstants>
</PropertyGroup>
@@ -71,9 +64,23 @@
<ProjectReference Include="..\CrowDbgShared\CrowDbgShared.csproj" />
</ItemGroup>-->
+ <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'">
+ <Compile Include="src\GraphicBackends\Mono.Cairo\**\*.*"
+ Exclude="src\GraphicBackends\Mono.Cairo\NativeMethods-internal.cs" />
+ </ItemGroup>
+
<ItemGroup>
<Content Include="..\Images\crow.png" Pack="true" PackagePath="" />
- <Compile Include="src\**\*.cs" Exclude="src\Mono.Cairo\NativeMethods-internal.cs" />
+ <Compile Include="src\**\*.cs" Exclude="src\GraphicBackends\**\*.*" />
<EmbeddedResource Include="Templates\*.*">
<LogicalName>Crow.%(Filename)%(Extension)</LogicalName>
</EmbeddedResource>
diff --git a/Crow/src/Cairo/CairoHelpers.cs b/Crow/src/Cairo/CairoHelpers.cs
index a2e036ac..ea9a94ba 100644
--- a/Crow/src/Cairo/CairoHelpers.cs
+++ b/Crow/src/Cairo/CairoHelpers.cs
@@ -1,38 +1,14 @@
-//
-// CairoHelpers.cs
+// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
-// Author:
-// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using Crow.Drawing;
namespace Crow
{
public static class CairoHelpers
- {
+ {
public static T Clamp<T>(this T val, T min, T max) where T : IComparable<T>
{
if (val.CompareTo(min) < 0) return min;
@@ -57,18 +33,18 @@ namespace Crow
return arr[minp];
}
- public static void CairoRectangle(Cairo.Context gr, RectangleD r, double radius, double stroke = 0.0)
+ public static void CairoRectangle(Context gr, RectangleD r, double radius, double stroke = 0.0)
{
if (radius > 0)
DrawRoundedRectangle (gr, r, radius, stroke);
else
gr.Rectangle (r, stroke);
}
- public static void CairoCircle(Cairo.Context gr, RectangleD r)
+ public static void CairoCircle(Context gr, RectangleD r)
{
gr.Arc(r.X + r.Width/2.0, r.Y + r.Height/2.0, Math.Min(r.Width,r.Height)/2.0, 0, 2.0*Math.PI);
}
- public static void DrawRoundedRectangle(Cairo.Context gr, RectangleD r, double radius, double stroke = 0.0)
+ public static void DrawRoundedRectangle(Context gr, RectangleD r, double radius, double stroke = 0.0)
{
if (stroke>0.0) {
gr.LineWidth = stroke;
@@ -78,9 +54,9 @@ namespace Crow
}else
DrawRoundedRectangle(gr, r.X, r.Y, r.Width, r.Height, radius);
}
- public static void DrawRoundedRectangle(Cairo.Context gr, double x, double y, double width, double height, double radius)
+ public static void DrawRoundedRectangle(Context gr, double x, double y, double width, double height, double radius)
{
- gr.Save();
+ //gr.Save();
if ((radius > height / 2) || (radius > width / 2))
radius = min(height / 2, width / 2);
@@ -94,11 +70,11 @@ namespace Crow
gr.LineTo(x + radius, y + height);
gr.Arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI);
gr.ClosePath();
- gr.Restore();
+ //gr.Restore();
}
- public static void StrokeRaisedRectangle(Cairo.Context gr, Rectangle r, double width = 1)
+ public static void StrokeRaisedRectangle(Context gr, Rectangle r, double width = 1)
{
- gr.Save();
+ //gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSource(Colors.White);
@@ -113,11 +89,11 @@ namespace Crow
gr.LineTo(r.BottomLeft);
gr.Stroke();
- gr.Restore();
+ //gr.Restore();
}
- public static void StrokeLoweredRectangle(Cairo.Context gr, Rectangle r, double width = 1)
+ public static void StrokeLoweredRectangle(Context gr, Rectangle r, double width = 1)
{
- gr.Save();
+ //gr.Save();
r.Inflate((int)-width / 2, (int)-width / 2);
gr.LineWidth = width;
gr.SetSource(Colors.DarkGrey);
@@ -131,7 +107,7 @@ namespace Crow
gr.LineTo(r.BottomLeft);
gr.Stroke();
- gr.Restore();
+ //gr.Restore();
}
}
}
diff --git a/Crow/src/DebugUtils/PerformanceMeasure.cs b/Crow/src/DebugUtils/PerformanceMeasure.cs
index f4cf76a8..8cd72d97 100644
--- a/Crow/src/DebugUtils/PerformanceMeasure.cs
+++ b/Crow/src/DebugUtils/PerformanceMeasure.cs
@@ -29,7 +29,7 @@ namespace Crow
public static void InitMeasures () {
Measures = new PerformanceMeasure[4];
Measures[(int)Kind.Update] = new PerformanceMeasure (Kind.Update, 1);
- Measures[(int)Kind.Clipping] = new PerformanceMeasure (Kind.Clipping, 1);
+ Measures[(int)Kind.Clipping] = new PerformanceMeasure (Kind.Clipping, 0);
Measures[(int)Kind.Layouting] = new PerformanceMeasure (Kind.Layouting, 1);
Measures[(int)Kind.Drawing] = new PerformanceMeasure (Kind.Drawing, 1);
}
diff --git a/Crow/src/ExtensionsMethods.cs b/Crow/src/ExtensionsMethods.cs
index c435f7ca..bc926877 100644
--- a/Crow/src/ExtensionsMethods.cs
+++ b/Crow/src/ExtensionsMethods.cs
@@ -9,13 +9,15 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
+using Crow.Drawing;
+
namespace Crow
{
public static class ExtensionsMethods
{
#region Cairo extensions
- public static void Rectangle(this Cairo.Context ctx, Rectangle r, double stroke = 0.0)
+ public static void Rectangle(this Context ctx, Rectangle r, double stroke = 0.0)
{
if (stroke > 0.0) {
ctx.LineWidth = stroke;
@@ -49,7 +51,7 @@ namespace Crow
public static PointD Multiply(this PointD p1, double v){
return new PointD(p1.X * v, p1.Y * v);
}
- public static void DrawCote(this Cairo.Context ctx, PointD p1, PointD p2,
+ public static void DrawCote(this Context ctx, PointD p1, PointD p2,
double stroke = 1.0, bool fill = false, double arrowWidth = 3.0, double arrowLength = 7.0)
{
PointD vDir = p2.Substract(p1);
@@ -86,7 +88,7 @@ namespace Crow
ctx.LineWidth = stroke;
ctx.Stroke ();
}
- public static void DrawCoteInverse(this Cairo.Context ctx, PointD p1, PointD p2,
+ public static void DrawCoteInverse(this Context ctx, PointD p1, PointD p2,
double stroke = 1.0, bool fill = false, double arrowWidth = 3.0, double arrowLength = 7.0)
{
PointD vDir = p2.Substract(p1);
@@ -118,7 +120,7 @@ namespace Crow
ctx.LineWidth = stroke;
ctx.Stroke ();
}
- public static void DrawCoteFixed(this Cairo.Context ctx, PointD p1, PointD p2,
+ public static void DrawCoteFixed(this Context ctx, PointD p1, PointD p2,
double stroke = 1.0, double coteWidth = 3.0)
{
PointD vDir = p2.Substract(p1);
@@ -136,7 +138,7 @@ namespace Crow
ctx.Stroke ();
}
- public static void AddColorStop(this Cairo.Gradient grad, double offset, Color c)
+ public static void AddColorStop(this Gradient grad, double offset, Color c)
{
grad.AddColorStop (offset, c);
}
diff --git a/Crow/src/Fill/BmpPicture.cs b/Crow/src/Fill/BmpPicture.cs
index 0f67323d..8b72b8b3 100644
--- a/Crow/src/Fill/BmpPicture.cs
+++ b/Crow/src/Fill/BmpPicture.cs
@@ -5,7 +5,8 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
-using Crow.Cairo;
+
+using Crow.Drawing;
namespace Crow
{
@@ -30,7 +31,7 @@ namespace Crow
/// <summary>
/// load the image for rendering from the path given as argument
/// </summary>
- void load (Interface iFace) {
+ public override void load (Interface iFace) {
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures[Path];
image = (byte[])sp.Data;
@@ -47,6 +48,9 @@ namespace Crow
#if STB_SHARP
StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
image = new byte[stbi.Data.Length];
+ #if VKVG
+ Array.Copy (stbi.Data, image, stbi.Data.Length);
+ #else
//rgba to argb for cairo.
for (int i = 0; i < stbi.Data.Length; i += 4) {
image[i] = stbi.Data[i + 2];
@@ -54,17 +58,22 @@ namespace Crow
image[i + 2] = stbi.Data[i];
image[i + 3] = stbi.Data[i + 3];
}
+ #endif
Dimensions = new Size (stbi.Width, stbi.Height);
#else
using (StbImage stbi = new StbImage (stream)) {
image = new byte [stbi.Size];
- //rgba to argb for cairo.
+ #if VKVG
+ Marshal.Copy (stbi.Handle, image, 0, stbi.Size);
+ #else
for (int i = 0; i < stbi.Size; i+=4) {
+ //rgba to argb for cairo. ???? looks like bgra to me.
image [i] = Marshal.ReadByte (stbi.Handle, i + 2);
image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1);
image [i + 2] = Marshal.ReadByte (stbi.Handle, i);
image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3);
}
+ #endif
Dimensions = new Size (stbi.Width, stbi.Height);
}
#endif
@@ -98,7 +107,7 @@ namespace Crow
}*/
#region implemented abstract members of Fill
-
+ public override bool IsLoaded => image != null;
public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
{
if (image == null)
@@ -119,14 +128,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, 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 ();
}
@@ -163,18 +179,26 @@ namespace Crow
widthRatio = heightRatio;
}
- gr.Save ();
+ //gr.Save ();
+
+ Matrix m = gr.Matrix;
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, 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 ();
}
- gr.Restore ();
+
+ gr.Matrix = m;
+ //gr.Restore ();
}
}
}
diff --git a/Crow/src/Fill/Fill.cs b/Crow/src/Fill/Fill.cs
index a11b666e..2faeca80 100644
--- a/Crow/src/Fill/Fill.cs
+++ b/Crow/src/Fill/Fill.cs
@@ -1,9 +1,9 @@
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// 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)
using System;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Fill/Gradient.cs b/Crow/src/Fill/Gradient.cs
index ac6a638e..d0b4b653 100644
--- a/Crow/src/Fill/Gradient.cs
+++ b/Crow/src/Fill/Gradient.cs
@@ -1,32 +1,11 @@
-//
-// Gradient.cs
+// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
-// Author:
-// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
using System.Collections.Generic;
-using Crow.Cairo;
+
+using Crow.Drawing;
namespace Crow
{
@@ -81,7 +60,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);
@@ -103,7 +82,7 @@ namespace Crow
}
ctx.SetSource (grad);
- grad.Dispose ();
+ grad.Dispose ();*/
}
#endregion
diff --git a/Crow/src/Fill/Picture.cs b/Crow/src/Fill/Picture.cs
index c9b23404..b915f6d4 100644
--- a/Crow/src/Fill/Picture.cs
+++ b/Crow/src/Fill/Picture.cs
@@ -1,33 +1,12 @@
-//
-// Picture.cs
+// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
-// Author:
-// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
using System.IO;
-using Crow.Cairo;
+
using System.Collections.Generic;
+using Crow.Drawing;
namespace Crow
{
@@ -58,7 +37,7 @@ namespace Crow
/// <summary>
/// unscaled dimensions fetched on loading
/// </summary>
- public Size Dimensions;
+ public Size Dimensions { get; protected set; }
/// <summary>
/// if true and image has to be scalled, it will be scaled in both direction
/// equaly
@@ -94,7 +73,8 @@ namespace Crow
/// <param name="rect">bounds of the target surface to paint</param>
/// <param name="subPart">used for svg only</param>
public abstract void Paint(Interface iFace, Context ctx, Rectangle rect, string subPart = "");
-
+ public abstract bool IsLoaded { get; }
+ public abstract void load (Interface iface);
#region Operators
public static implicit operator Picture(string path) => Parse (path) as Picture;
public static implicit operator string(Picture _pic) => _pic == null ? null : _pic.Path;
diff --git a/Crow/src/Fill/SolidColor.cs b/Crow/src/Fill/SolidColor.cs
index 40c7cdc1..6977a8bc 100644
--- a/Crow/src/Fill/SolidColor.cs
+++ b/Crow/src/Fill/SolidColor.cs
@@ -1,4 +1,4 @@
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// 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)
@@ -9,9 +9,8 @@ using System.Text;
using System.Xml.Serialization;
using System.Reflection;
using System.Diagnostics;
-using Crow.Cairo;
-
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Fill/SvgPicture.cs b/Crow/src/Fill/SvgPicture.cs
index fcd5c4d2..80d380ed 100644
--- a/Crow/src/Fill/SvgPicture.cs
+++ b/Crow/src/Fill/SvgPicture.cs
@@ -4,7 +4,8 @@
using System;
using System.IO;
-using Crow.Cairo;
+
+using Crow.Drawing;
namespace Crow
{
@@ -13,7 +14,7 @@ namespace Crow
/// </summary>
public class SvgPicture : Picture
{
- Rsvg.Handle hSVG;
+ SvgHandle hSVG;
#region CTOR
/// <summary>
@@ -27,45 +28,49 @@ namespace Crow
public SvgPicture (string path) : base(path) {}
#endregion
- bool load (Interface iFace)
+ public override void load (Interface iFace)
{
- if (string.IsNullOrEmpty(Path))
- return false;
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures [Path];
- hSVG = (Rsvg.Handle)sp.Data;
+ hSVG = (SvgHandle)sp.Data;
Dimensions = sp.Dims;
- return true;
+ return;
}
using (Stream stream = iFace.GetStreamFromPath (Path))
- load (stream);
+ load (iFace, stream);
iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
- return true;
}
- void load (Stream stream) {
+ void load (Interface iface, Stream stream) {
using (BinaryReader sr = new BinaryReader (stream)) {
- hSVG = new Rsvg.Handle (sr.ReadBytes ((int)stream.Length));
- Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
+#if VKVG
+ hSVG = new SvgHandle (iface.vkvgDevice, sr.ReadBytes ((int)stream.Length));
+#else
+ hSVG = new SvgHandle (sr.ReadBytes ((int)stream.Length));
+#endif
+ Dimensions = hSVG.Dimensions;
}
}
- internal static sharedPicture CreateSharedPicture (Stream stream) {
+ internal static sharedPicture CreateSharedPicture (Interface iface, Stream stream) {
SvgPicture pic = new SvgPicture ();
- pic.load (stream);
+ pic.load (iface, stream);
return new sharedPicture (pic.hSVG, pic.Dimensions);
}
- public void LoadSvgFragment (string fragment) {
- hSVG = new Rsvg.Handle (System.Text.Encoding.Unicode.GetBytes(fragment));
+ public void LoadSvgFragment (Interface iface, string fragment) {
+#if VKVG
+ hSVG = new SvgHandle (iface.vkvgDevice, System.Text.Encoding.Unicode.GetBytes(fragment));
+#else
+ hSVG = new SvgHandle (System.Text.Encoding.Unicode.GetBytes(fragment));
+#endif
Dimensions = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height);
}
#region implemented abstract members of Fill
-
+ public override bool IsLoaded => hSVG != null;
public override void SetAsSource (Interface iFace, Context ctx, Rectangle bounds = default(Rectangle))
{
if (hSVG == null)
- if (!load (iFace))
- return;
+ load (iFace);
float widthRatio = 1f;
float heightRatio = 1f;
@@ -82,16 +87,20 @@ 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);
- hSVG.RenderCairo (gr);
+ hSVG.Render (gr);
}
ctx.SetSource (tmp);
- }
+ }
}
#endregion
@@ -105,8 +114,7 @@ namespace Crow
public override void Paint (Interface iFace, Context gr, Rectangle rect, string subPart = "")
{
if (hSVG == null)
- if (!load (iFace))
- return;
+ load (iFace);
float widthRatio = 1f;
float heightRatio = 1f;
@@ -129,14 +137,14 @@ namespace Crow
gr.Translate (((float)rect.Width/widthRatio - Dimensions.Width)/2f, ((float)rect.Height/heightRatio - Dimensions.Height)/2f);
if (string.IsNullOrEmpty (subPart))
- hSVG.RenderCairo (gr);
+ hSVG.Render (gr);
else {
string[] parts = subPart.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string p in parts)
- hSVG.RenderCairoSub (gr, "#" + subPart);
+ hSVG.Render (gr, "#" + subPart);
}
- gr.Restore ();
+ gr.Restore ();
}
}
}
diff --git a/Crow/src/Font.cs b/Crow/src/Font.cs
index 1ec0b2cc..0d6534ff 100644
--- a/Crow/src/Font.cs
+++ b/Crow/src/Font.cs
@@ -3,8 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using Crow.Cairo;
-//using FastEnumUtility;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Mono.Cairo/Antialias.cs b/Crow/src/GraphicBackends/Mono.Cairo/Antialias.cs
index 64da6443..fd98f604 100644
--- a/Crow/src/Mono.Cairo/Antialias.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Antialias.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Antialias
diff --git a/Crow/src/Mono.Cairo/Cairo.cs b/Crow/src/GraphicBackends/Mono.Cairo/Cairo.cs
index c32c00d8..6428304f 100644
--- a/Crow/src/Mono.Cairo/Cairo.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Cairo.cs
@@ -34,7 +34,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public static class CairoAPI {
static public int Version {
diff --git a/Crow/src/Mono.Cairo/CairoDebug.cs b/Crow/src/GraphicBackends/Mono.Cairo/CairoDebug.cs
index a669d841..890793da 100644
--- a/Crow/src/Mono.Cairo/CairoDebug.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/CairoDebug.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
static class CairoDebug
{
diff --git a/Crow/src/Mono.Cairo/Content.cs b/Crow/src/GraphicBackends/Mono.Cairo/Content.cs
index f14305a4..13927c1d 100644
--- a/Crow/src/Mono.Cairo/Content.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Content.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
//[Flags]
diff --git a/Crow/src/Mono.Cairo/Context.cs b/Crow/src/GraphicBackends/Mono.Cairo/Context.cs
index 5ed2bbd4..c69a4231 100644
--- a/Crow/src/Mono.Cairo/Context.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Context.cs
@@ -38,7 +38,7 @@ using System;
using System.Runtime.InteropServices;
using System.Text;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
[Obsolete ("Renamed Cairo.Context per suggestion from cairo binding guidelines.")]
public class Graphics : Context {
diff --git a/Crow/src/Mono.Cairo/DRMDevice.cs b/Crow/src/GraphicBackends/Mono.Cairo/DRMDevice.cs
index 05e142cb..c08ad030 100644
--- a/Crow/src/Mono.Cairo/DRMDevice.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/DRMDevice.cs
@@ -29,7 +29,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class DRMDevice : Device
{
diff --git a/Crow/src/Mono.Cairo/DRMSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/DRMSurface.cs
index f624967f..b1fcfb76 100644
--- a/Crow/src/Mono.Cairo/DRMSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/DRMSurface.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class DRMSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/Device.cs b/Crow/src/GraphicBackends/Mono.Cairo/Device.cs
index 484264f0..426d4ca2 100644
--- a/Crow/src/Mono.Cairo/Device.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Device.cs
@@ -29,7 +29,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class Device : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/DirectFBSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/DirectFBSurface.cs
index 64431574..4f52ec72 100644
--- a/Crow/src/Mono.Cairo/DirectFBSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/DirectFBSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class DirectFBSurface : Surface
{
internal DirectFBSurface (IntPtr handle, bool owns) : base (handle, owns)
diff --git a/Crow/src/Mono.Cairo/Distance.cs b/Crow/src/GraphicBackends/Mono.Cairo/Distance.cs
index d716ab1f..eaa7d5a3 100644
--- a/Crow/src/Mono.Cairo/Distance.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Distance.cs
@@ -34,7 +34,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public struct Distance
{
diff --git a/Crow/src/Mono.Cairo/EGLDevice.cs b/Crow/src/GraphicBackends/Mono.Cairo/EGLDevice.cs
index 44590c70..93150884 100644
--- a/Crow/src/Mono.Cairo/EGLDevice.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/EGLDevice.cs
@@ -29,7 +29,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class EGLDevice : Device
{
diff --git a/Crow/src/Mono.Cairo/Extend.cs b/Crow/src/GraphicBackends/Mono.Cairo/Extend.cs
index 4af536dc..01a7969d 100644
--- a/Crow/src/Mono.Cairo/Extend.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Extend.cs
@@ -32,7 +32,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Extend
diff --git a/Crow/src/Mono.Cairo/FillRule.cs b/Crow/src/GraphicBackends/Mono.Cairo/FillRule.cs
index 80f61ed5..314a7830 100644
--- a/Crow/src/Mono.Cairo/FillRule.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FillRule.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum FillRule
diff --git a/Crow/src/Mono.Cairo/Filter.cs b/Crow/src/GraphicBackends/Mono.Cairo/Filter.cs
index a73ea58d..5b521048 100644
--- a/Crow/src/Mono.Cairo/Filter.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Filter.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Filter
diff --git a/Crow/src/Mono.Cairo/FontExtents.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontExtents.cs
index ea26d9bb..99a26d2c 100644
--- a/Crow/src/Mono.Cairo/FontExtents.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontExtents.cs
@@ -34,7 +34,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
[StructLayout (LayoutKind.Sequential)]
public struct FontExtents
diff --git a/Crow/src/Mono.Cairo/FontFace.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontFace.cs
index 64c428e2..e4fd1a6e 100644
--- a/Crow/src/Mono.Cairo/FontFace.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontFace.cs
@@ -32,7 +32,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class FontFace : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/FontOptions.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontOptions.cs
index f90a3a4d..977b6993 100644
--- a/Crow/src/Mono.Cairo/FontOptions.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontOptions.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class FontOptions : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/FontSlant.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontSlant.cs
index b3d8a1a2..4ce74a24 100644
--- a/Crow/src/Mono.Cairo/FontSlant.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontSlant.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum FontSlant
diff --git a/Crow/src/Mono.Cairo/FontType.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontType.cs
index 5db44d4e..80d672c4 100644
--- a/Crow/src/Mono.Cairo/FontType.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontType.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public enum FontType
diff --git a/Crow/src/Mono.Cairo/FontWeight.cs b/Crow/src/GraphicBackends/Mono.Cairo/FontWeight.cs
index 0b8fc6a8..51c0e8d2 100644
--- a/Crow/src/Mono.Cairo/FontWeight.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/FontWeight.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum FontWeight
diff --git a/Crow/src/Mono.Cairo/Format.cs b/Crow/src/GraphicBackends/Mono.Cairo/Format.cs
index 54c8be1e..4078b168 100644
--- a/Crow/src/Mono.Cairo/Format.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Format.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Format
diff --git a/Crow/src/Mono.Cairo/GLSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/GLSurface.cs
index 60384b02..54522f5c 100644
--- a/Crow/src/Mono.Cairo/GLSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/GLSurface.cs
@@ -30,7 +30,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class GLSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/GLXDevice.cs b/Crow/src/GraphicBackends/Mono.Cairo/GLXDevice.cs
index 00cbce1f..086cf1f4 100644
--- a/Crow/src/Mono.Cairo/GLXDevice.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/GLXDevice.cs
@@ -29,7 +29,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class GLXDevice : Device
{
diff --git a/Crow/src/Mono.Cairo/GlitzSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/GlitzSurface.cs
index 4aa24983..fc12c673 100644
--- a/Crow/src/Mono.Cairo/GlitzSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/GlitzSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class GlitzSurface : Surface
{
internal GlitzSurface (IntPtr handle, bool owns) : base (handle, owns)
diff --git a/Crow/src/Mono.Cairo/Glyph.cs b/Crow/src/GraphicBackends/Mono.Cairo/Glyph.cs
index ad511562..c015e6de 100644
--- a/Crow/src/Mono.Cairo/Glyph.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Glyph.cs
@@ -30,7 +30,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
[StructLayout(LayoutKind.Sequential)]
public struct Glyph
diff --git a/Crow/src/Mono.Cairo/Gradient.cs b/Crow/src/GraphicBackends/Mono.Cairo/Gradient.cs
index a1799e3f..c7d2ea32 100644
--- a/Crow/src/Mono.Cairo/Gradient.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Gradient.cs
@@ -29,7 +29,7 @@
using System;
using Color = Crow.Color;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class Gradient : Pattern
{
diff --git a/Crow/src/Mono.Cairo/HintMetrics.cs b/Crow/src/GraphicBackends/Mono.Cairo/HintMetrics.cs
index d830f3eb..fbb78ad6 100644
--- a/Crow/src/Mono.Cairo/HintMetrics.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/HintMetrics.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum HintMetrics
diff --git a/Crow/src/Mono.Cairo/HintStyle.cs b/Crow/src/GraphicBackends/Mono.Cairo/HintStyle.cs
index 343daf3e..713dafae 100644
--- a/Crow/src/Mono.Cairo/HintStyle.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/HintStyle.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum HintStyle
diff --git a/Crow/src/Mono.Cairo/ImageSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/ImageSurface.cs
index 7c70569d..a1a182ca 100644
--- a/Crow/src/Mono.Cairo/ImageSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/ImageSurface.cs
@@ -35,7 +35,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class ImageSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/LineCap.cs b/Crow/src/GraphicBackends/Mono.Cairo/LineCap.cs
index 1560cda4..b9fcb220 100644
--- a/Crow/src/Mono.Cairo/LineCap.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/LineCap.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum LineCap
diff --git a/Crow/src/Mono.Cairo/LineJoin.cs b/Crow/src/GraphicBackends/Mono.Cairo/LineJoin.cs
index 1d5389b5..2ec44b69 100644
--- a/Crow/src/Mono.Cairo/LineJoin.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/LineJoin.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum LineJoin
diff --git a/Crow/src/Mono.Cairo/LinearGradient.cs b/Crow/src/GraphicBackends/Mono.Cairo/LinearGradient.cs
index 100d1e6d..69d9a939 100644
--- a/Crow/src/Mono.Cairo/LinearGradient.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/LinearGradient.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class LinearGradient : Gradient
{
diff --git a/Crow/src/Mono.Cairo/Matrix.cs b/Crow/src/GraphicBackends/Mono.Cairo/Matrix.cs
index 7d5a6acd..fc9f393f 100644
--- a/Crow/src/Mono.Cairo/Matrix.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Matrix.cs
@@ -34,7 +34,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
[StructLayout(LayoutKind.Sequential)]
public class Matrix //: ICloneable
diff --git a/Crow/src/Mono.Cairo/MeshPattern.cs b/Crow/src/GraphicBackends/Mono.Cairo/MeshPattern.cs
index 83da70b1..99cd72c1 100644
--- a/Crow/src/Mono.Cairo/MeshPattern.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/MeshPattern.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class MeshPattern : Pattern
{
diff --git a/Crow/src/Mono.Cairo/NativeMethods-internal.cs b/Crow/src/GraphicBackends/Mono.Cairo/NativeMethods-internal.cs
index 6e6d507c..6e6d507c 100644
--- a/Crow/src/Mono.Cairo/NativeMethods-internal.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/NativeMethods-internal.cs
diff --git a/Crow/src/Mono.Cairo/NativeMethods.cs b/Crow/src/GraphicBackends/Mono.Cairo/NativeMethods.cs
index 4f93c411..6bce9f19 100644
--- a/Crow/src/Mono.Cairo/NativeMethods.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/NativeMethods.cs
@@ -34,7 +34,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
// sort the functions like in the following page so it is easier to find what is missing
// http://cairographics.org/manual/index-all.html
diff --git a/Crow/src/Mono.Cairo/Operator.cs b/Crow/src/GraphicBackends/Mono.Cairo/Operator.cs
index 1c11cccc..7de2d11e 100644
--- a/Crow/src/Mono.Cairo/Operator.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Operator.cs
@@ -31,7 +31,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Operator
diff --git a/Crow/src/Mono.Cairo/PSSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/PSSurface.cs
index cf90794e..ca3c1d7d 100644
--- a/Crow/src/Mono.Cairo/PSSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/PSSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class PSSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/Path.cs b/Crow/src/GraphicBackends/Mono.Cairo/Path.cs
index a55f03b0..9d5e9456 100644
--- a/Crow/src/Mono.Cairo/Path.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Path.cs
@@ -30,9 +30,9 @@
using System;
using System.Runtime.InteropServices;
-using Crow.Cairo;
-namespace Crow.Cairo {
+
+namespace Crow.Drawing {
public class Path : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/Pattern.cs b/Crow/src/GraphicBackends/Mono.Cairo/Pattern.cs
index 3e933a19..1180e632 100644
--- a/Crow/src/Mono.Cairo/Pattern.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Pattern.cs
@@ -30,7 +30,7 @@
using System;
using System.Collections;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class Pattern : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/PatternType.cs b/Crow/src/GraphicBackends/Mono.Cairo/PatternType.cs
index deac3ab7..008d8e55 100644
--- a/Crow/src/Mono.Cairo/PatternType.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/PatternType.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public enum PatternType
diff --git a/Crow/src/Mono.Cairo/PdfSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/PdfSurface.cs
index 09a2d126..16287b76 100644
--- a/Crow/src/Mono.Cairo/PdfSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/PdfSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class PdfSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/RadialGradient.cs b/Crow/src/GraphicBackends/Mono.Cairo/RadialGradient.cs
index 6abe2671..e76f7df1 100644
--- a/Crow/src/Mono.Cairo/RadialGradient.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/RadialGradient.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class RadialGradient : Gradient
{
diff --git a/Crow/src/Mono.Cairo/Region.cs b/Crow/src/GraphicBackends/Mono.Cairo/Region.cs
index f2c111d7..efb8e8f0 100644
--- a/Crow/src/Mono.Cairo/Region.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Region.cs
@@ -23,7 +23,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
[StructLayout(LayoutKind.Sequential)]
public struct RectangleList {
@@ -198,5 +198,6 @@ namespace Crow.Cairo
NativeMethods.cairo_region_destroy (Handle);
handle = NativeMethods.cairo_region_create ();
}
+ public bool OverlapOut (Crow.Rectangle rectangle) => Contains (p.Slot) == RegionOverlap.Out;
}
}
diff --git a/Crow/src/Mono.Cairo/ScaledFont.cs b/Crow/src/GraphicBackends/Mono.Cairo/ScaledFont.cs
index 594d1be9..1d70646d 100644
--- a/Crow/src/Mono.Cairo/ScaledFont.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/ScaledFont.cs
@@ -26,7 +26,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class ScaledFont : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/SolidPattern.cs b/Crow/src/GraphicBackends/Mono.Cairo/SolidPattern.cs
index 6cd89f85..5c5da80b 100644
--- a/Crow/src/Mono.Cairo/SolidPattern.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SolidPattern.cs
@@ -29,7 +29,7 @@
using System;
using Color = Crow.Color;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class SolidPattern : Pattern
{
diff --git a/Crow/src/Mono.Cairo/Status.cs b/Crow/src/GraphicBackends/Mono.Cairo/Status.cs
index 2df15580..9a0b8eed 100644
--- a/Crow/src/Mono.Cairo/Status.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Status.cs
@@ -32,7 +32,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum Status
diff --git a/Crow/src/Mono.Cairo/SubpixelOrder.cs b/Crow/src/GraphicBackends/Mono.Cairo/SubpixelOrder.cs
index 95f3cbee..a67776df 100644
--- a/Crow/src/Mono.Cairo/SubpixelOrder.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SubpixelOrder.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public enum SubpixelOrder
diff --git a/Crow/src/Mono.Cairo/Surface.cs b/Crow/src/GraphicBackends/Mono.Cairo/Surface.cs
index 56c1553f..4b31990c 100644
--- a/Crow/src/Mono.Cairo/Surface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Surface.cs
@@ -36,7 +36,7 @@
using System;
using System.Collections;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class Surface : IDisposable
{
diff --git a/Crow/src/Mono.Cairo/SurfacePattern.cs b/Crow/src/GraphicBackends/Mono.Cairo/SurfacePattern.cs
index 53a90d38..6c4539c8 100644
--- a/Crow/src/Mono.Cairo/SurfacePattern.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SurfacePattern.cs
@@ -29,7 +29,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class SurfacePattern : Pattern
{
diff --git a/Crow/src/Mono.Cairo/SurfaceType.cs b/Crow/src/GraphicBackends/Mono.Cairo/SurfaceType.cs
index bd992db0..5333e536 100644
--- a/Crow/src/Mono.Cairo/SurfaceType.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SurfaceType.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public enum SurfaceType
diff --git a/Crow/src/Mono.Cairo/SvgSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/SvgSurface.cs
index c7d72988..4e22148d 100644
--- a/Crow/src/Mono.Cairo/SvgSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SvgSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class SvgSurface : Surface
{
diff --git a/Crow/src/Mono.Cairo/SvgVersion.cs b/Crow/src/GraphicBackends/Mono.Cairo/SvgVersion.cs
index 916fb861..85bc6caf 100644
--- a/Crow/src/Mono.Cairo/SvgVersion.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/SvgVersion.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public enum SvgVersion
diff --git a/Crow/src/Mono.Cairo/TextExtents.cs b/Crow/src/GraphicBackends/Mono.Cairo/TextExtents.cs
index 965ca046..4dd606fd 100644
--- a/Crow/src/Mono.Cairo/TextExtents.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/TextExtents.cs
@@ -31,7 +31,7 @@
using System;
using System.Runtime.InteropServices;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
[StructLayout (LayoutKind.Sequential)]
public struct TextExtents
diff --git a/Crow/src/Mono.Cairo/WGLDevice.cs b/Crow/src/GraphicBackends/Mono.Cairo/WGLDevice.cs
index 308cfadd..fda7d93f 100644
--- a/Crow/src/Mono.Cairo/WGLDevice.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/WGLDevice.cs
@@ -29,7 +29,7 @@
//
using System;
-namespace Crow.Cairo
+namespace Crow.Drawing
{
public class WGLDevice : Device
{
diff --git a/Crow/src/Mono.Cairo/Win32Surface.cs b/Crow/src/GraphicBackends/Mono.Cairo/Win32Surface.cs
index 4776a19b..53b79e92 100644
--- a/Crow/src/Mono.Cairo/Win32Surface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/Win32Surface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class Win32Surface : Surface
{
diff --git a/Crow/src/Mono.Cairo/XcbSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/XcbSurface.cs
index 32a67848..72c4dbe8 100644
--- a/Crow/src/Mono.Cairo/XcbSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/XcbSurface.cs
@@ -28,7 +28,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class XcbSurface : Surface
{
internal XcbSurface (IntPtr handle, bool owns) : base (handle, owns)
diff --git a/Crow/src/Mono.Cairo/XlibSurface.cs b/Crow/src/GraphicBackends/Mono.Cairo/XlibSurface.cs
index 18e810bd..fbe9e01f 100644
--- a/Crow/src/Mono.Cairo/XlibSurface.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/XlibSurface.cs
@@ -36,7 +36,7 @@
using System;
-namespace Crow.Cairo {
+namespace Crow.Drawing {
public class XlibSurface : Surface
{
diff --git a/Crow/src/rsvg/Handle.cs b/Crow/src/GraphicBackends/Mono.Cairo/rsvg/SvgHandle.cs
index ca06ad25..1477b14f 100644
--- a/Crow/src/rsvg/Handle.cs
+++ b/Crow/src/GraphicBackends/Mono.Cairo/rsvg/SvgHandle.cs
@@ -1,14 +1,11 @@
//Copyright GPL2
-using Crow.Cairo;
+using System;
+using System.Runtime.InteropServices;
+namespace Crow.Drawing {
-namespace Rsvg {
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
-
- public sealed class Handle {
+ public sealed class SvgHandle : IDisposable {
const string lib = "rsvg-2.40";
public IntPtr Raw;
@@ -40,16 +37,16 @@ namespace Rsvg {
[DllImport (lib)]
static extern IntPtr rsvg_handle_get_metadata (IntPtr raw);
- public Handle ()
+ public SvgHandle ()
{
Raw = rsvg_handle_new();
}
- public Handle (byte[] data)
+ public SvgHandle (byte[] data)
{
Raw = rsvg_handle_new_from_data(data, new UIntPtr ((ulong) (data == null ? 0 : data.Length)), out IntPtr error);
if (error != IntPtr.Zero) throw new Exception (error.ToString());
}
- public Handle (string file_name)
+ public SvgHandle (string file_name)
{
Raw = rsvg_handle_new_from_file(file_name, out IntPtr error);
if (error != IntPtr.Zero) throw new Exception (error.ToString());
@@ -60,30 +57,42 @@ namespace Rsvg {
public void SetDpiXY (double dpi_x, double dpi_y) => rsvg_handle_set_dpi_x_y (Raw, dpi_x, dpi_y);
- public void RenderCairo(Context cr) =>
+ public void Render(Context cr) =>
rsvg_handle_render_cairo (Raw, cr == null ? IntPtr.Zero : cr.Handle);
- public void RenderCairoSub (Context cr, string id) =>
+ public void Render (Context cr, string id) =>
rsvg_handle_render_cairo_sub (Raw, cr == null ? IntPtr.Zero : cr.Handle, id);
- public DimensionData Dimensions {
+ [StructLayout(LayoutKind.Sequential)]
+ struct DimensionData {
+
+ public int Width;
+ public int Height;
+ public double Em;
+ public double Ex;
+
+ public static DimensionData Zero = new DimensionData ();
+
+ public static DimensionData New(IntPtr raw) {
+ if (raw == IntPtr.Zero)
+ return DimensionData.Zero;
+ return (DimensionData) Marshal.PtrToStructure (raw, typeof (DimensionData));
+ }
+ }
+ public Size Dimensions {
get {
DimensionData dimension_data;
IntPtr native_dimension_data = Marshal.AllocHGlobal (Marshal.SizeOf (typeof (DimensionData)));
rsvg_handle_get_dimensions(Raw, native_dimension_data);
dimension_data = DimensionData.New (native_dimension_data);
Marshal.FreeHGlobal (native_dimension_data);
- return dimension_data;
+ return new Size (dimension_data.Width, dimension_data.Height);
}
}
- public bool Close() {
+ public void Dispose() {
bool raw_ret = rsvg_handle_close(Raw, out IntPtr error);
- if (error != IntPtr.Zero) throw new Exception (error.ToString());
- return raw_ret;
+ if (error != IntPtr.Zero) throw new Exception (error.ToString());
}
-
- public string Title => throw new NotSupportedException ();
- public string Metadata => throw new NotSupportedException ();
}
}
diff --git a/Crow/src/GraphicBackends/vkvg/Context.cs b/Crow/src/GraphicBackends/vkvg/Context.cs
new file mode 100644
index 00000000..bf638de3
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Context.cs
@@ -0,0 +1,386 @@
+// Copyright (c) 2018-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.Text;
+using Crow;
+
+namespace Crow.Drawing
+{
+ public class Context : IDisposable
+ {
+
+ IntPtr handle = IntPtr.Zero;
+
+ public Context(Surface surf)
+ {
+ handle = NativeMethods.vkvg_create(surf.Handle);
+ this.FillRule = FillRule.NonZero;
+ }
+ ~Context()
+ {
+ Dispose(false);
+ }
+
+ public IntPtr Handle => handle;
+
+ public void AddReference()
+ {
+ NativeMethods.vkvg_reference(handle);
+ }
+ public uint References() => NativeMethods.vkvg_get_reference_count(handle);
+
+ public double LineWidth
+ {
+ get => NativeMethods.vkvg_get_line_width(handle);
+ set { NativeMethods.vkvg_set_line_width(handle, (float)value); }
+ }
+ public LineJoin LineJoin
+ {
+ get => NativeMethods.vkvg_get_line_join(handle);
+ set { NativeMethods.vkvg_set_line_join(handle, value); }
+ }
+ public LineCap LineCap
+ {
+ get => NativeMethods.vkvg_get_line_cap(handle);
+ set { NativeMethods.vkvg_set_line_cap(handle, value); }
+ }
+ public uint FontSize
+ {
+ set { NativeMethods.vkvg_set_font_size(handle, value); }
+ }
+ public string FontFace
+ {
+ set { NativeMethods.vkvg_select_font_face(handle, value); }
+ }
+ public Operator Operator
+ {
+ set { NativeMethods.vkvg_set_operator(handle, value); }
+ get { return NativeMethods.vkvg_get_operator(handle); }
+ }
+ public FillRule FillRule
+ {
+ set { NativeMethods.vkvg_set_fill_rule(handle, value); }
+ get { return NativeMethods.vkvg_get_fill_rule(handle); }
+ }
+ public FontExtents FontExtents
+ {
+ get
+ {
+ FontExtents f_extents;
+ NativeMethods.vkvg_font_extents(handle, out f_extents);
+ return f_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
+ {
+ Matrix m;
+ NativeMethods.vkvg_get_matrix(handle, out m);
+ return m;
+ }
+ set
+ {
+ NativeMethods.vkvg_set_matrix(handle, ref value);
+ }
+ }
+ 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);
+ }
+ public void Save()
+ {
+ NativeMethods.vkvg_save(handle);
+ }
+ public void Restore()
+ {
+ NativeMethods.vkvg_restore(handle);
+ }
+ public void Flush()
+ {
+ NativeMethods.vkvg_flush(handle);
+ }
+ public void Clear()
+ {
+ NativeMethods.vkvg_clear(handle);
+ }
+ public void Paint()
+ {
+ 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);
+ }
+ public void Arc(double xc, double yc, double radius, double a1, double a2)
+ {
+ 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);
+ }
+ public void Rectangle(float x, float y, float width, float height)
+ {
+ NativeMethods.vkvg_rectangle(handle, x, y, width, height);
+ }
+ public void Scale(float sx, float sy)
+ {
+ NativeMethods.vkvg_scale(handle, sx, sy);
+ }
+ public void Translate(float dx, float dy)
+ {
+ NativeMethods.vkvg_translate(handle, dx, dy);
+ }
+ public void Rotate(float alpha)
+ {
+ NativeMethods.vkvg_rotate(handle, alpha);
+ }
+ public void ArcNegative(double xc, double yc, double radius, double a1, double a2)
+ {
+ NativeMethods.vkvg_arc_negative(handle, (float)xc, (float)yc, (float)radius, (float)a1, (float)a2);
+ }
+ public void Rectangle(double x, double y, double width, double height)
+ {
+ NativeMethods.vkvg_rectangle(handle, (float)x, (float)y, (float)width, (float)height);
+ }
+ public void Scale(double sx, double sy)
+ {
+ NativeMethods.vkvg_scale(handle, (float)sx, (float)sy);
+ }
+ public void Translate(double dx, double dy)
+ {
+ NativeMethods.vkvg_translate(handle, (float)dx, (float)dy);
+ }
+ public void Translate(PointD p)
+ {
+ NativeMethods.vkvg_translate(handle, (float)p.X, (float)p.Y);
+ }
+ public void Rotate(double alpha)
+ {
+ NativeMethods.vkvg_rotate(handle, (float)alpha);
+ }
+
+ public void Fill()
+ {
+ NativeMethods.vkvg_fill(handle);
+ }
+ public void FillPreserve()
+ {
+ NativeMethods.vkvg_fill_preserve(handle);
+ }
+ public void Stroke()
+ {
+ NativeMethods.vkvg_stroke(handle);
+ }
+ public void StrokePreserve()
+ {
+ NativeMethods.vkvg_stroke_preserve(handle);
+ }
+ public void Clip()
+ {
+ NativeMethods.vkvg_clip(handle);
+ }
+ public void ClipPreserve()
+ {
+ NativeMethods.vkvg_clip_preserve(handle);
+ }
+ public void ResetClip()
+ {
+ NativeMethods.vkvg_reset_clip(handle);
+ }
+ public void NewPath()
+ {
+ NativeMethods.vkvg_new_path(handle);
+ }
+ public void NewSubPath()
+ {
+ NativeMethods.vkvg_new_sub_path(handle);
+ }
+ public void ClosePath()
+ {
+ NativeMethods.vkvg_close_path(handle);
+ }
+ public void MoveTo(PointD p)
+ {
+ NativeMethods.vkvg_move_to(handle, (float)p.X, (float)p.Y);
+ }
+ public void MoveTo(Point p)
+ {
+ NativeMethods.vkvg_move_to(handle, p.X, p.Y);
+ }
+ public void MoveTo(float x, float y)
+ {
+ NativeMethods.vkvg_move_to(handle, x, y);
+ }
+ public void RelMoveTo(float x, float y)
+ {
+ NativeMethods.vkvg_rel_move_to(handle, x, y);
+ }
+ public void LineTo(float x, float y)
+ {
+ NativeMethods.vkvg_line_to(handle, x, y);
+ }
+ public void LineTo(Point p)
+ {
+ NativeMethods.vkvg_line_to(handle, p.X, p.Y);
+ }
+ public void LineTo(PointD p)
+ {
+ NativeMethods.vkvg_line_to(handle, (float)p.X, (float)p.Y);
+ }
+ public void RelLineTo(float x, float y)
+ {
+ NativeMethods.vkvg_rel_line_to(handle, x, y);
+ }
+ public void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
+ {
+ NativeMethods.vkvg_curve_to(handle, x1, y1, x2, y2, x3, y3);
+ }
+ public void RelCurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
+ {
+ NativeMethods.vkvg_rel_curve_to(handle, x1, y1, x2, y2, x3, y3);
+ }
+
+ public void MoveTo(double x, double y)
+ {
+ NativeMethods.vkvg_move_to(handle, (float)x, (float)y);
+ }
+ public void RelMoveTo(double x, double y)
+ {
+ NativeMethods.vkvg_rel_move_to(handle, (float)x, (float)y);
+ }
+ public void LineTo(double x, double y)
+ {
+ NativeMethods.vkvg_line_to(handle, (float)x, (float)y);
+ }
+ public void RelLineTo(double x, double y)
+ {
+ NativeMethods.vkvg_rel_line_to(handle, (float)x, (float)y);
+ }
+ public void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ NativeMethods.vkvg_curve_to(handle, (float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3);
+ }
+ public void RelCurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
+ {
+ NativeMethods.vkvg_rel_curve_to(handle, (float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3);
+ }
+
+ public void SetSource(Pattern pat)
+ {
+ NativeMethods.vkvg_set_source(handle, pat.Handle);
+ }
+ public void SetSource (Color color)
+ {
+ NativeMethods.vkvg_set_source_rgba (handle, (float)(color.R / 255.0), (float)(color.G / 255.0), (float)(color.B / 255.0), (float)(color.A / 255.0));
+ }
+ public void SetSource(float r, float g, float b, float a = 1f)
+ {
+ NativeMethods.vkvg_set_source_rgba(handle, r, g, b, a);
+ }
+ public void SetSource(double r, double g, double b, double a = 1.0)
+ {
+ NativeMethods.vkvg_set_source_rgba(handle, (float)r, (float)g, (float)b, (float)a);
+ }
+ public void SetSource(Surface surf, float x = 0f, float y = 0f)
+ {
+ NativeMethods.vkvg_set_source_surface(handle, surf.Handle, x, y);
+ }
+ public void SetSourceSurface(Surface surf, float x = 0f, float y = 0f)
+ {
+ NativeMethods.vkvg_set_source_surface(handle, surf.Handle, x, y);
+ }
+ public void RenderSvg(IntPtr nsvgImage, string subId = null)
+ {
+ 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
+ var byteCount = Encoding.UTF8.GetMaxByteCount(s.Length + 1);
+ var bytes = new byte[byteCount];
+ Encoding.UTF8.GetBytes(s, 0, s.Length, bytes, 0);
+ return bytes;
+ }
+
+ public float[] Dashes
+ {
+ set
+ {
+ if (value == null)
+ NativeMethods.vkvg_set_dash(handle, null, 0, 0);
+ else
+ NativeMethods.vkvg_set_dash(handle, value, (uint)value.Length, 0);
+ }
+ }
+
+
+ public void PushGroup () {
+
+ }
+ public void PopGroupToSource () {
+
+ }
+
+ #region IDisposable implementation
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.vkvg_destroy(handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
+ }
+}
+
diff --git a/Crow/src/GraphicBackends/vkvg/Device.cs b/Crow/src/GraphicBackends/vkvg/Device.cs
new file mode 100644
index 00000000..6ff0230c
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Device.cs
@@ -0,0 +1,50 @@
+// Copyright (c) 2018-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;
+
+namespace Crow.Drawing
+{
+ public class Device: IDisposable
+ {
+
+ IntPtr handle = IntPtr.Zero;
+
+ #region CTORS & DTOR
+ public Device (IntPtr instance, IntPtr phy, IntPtr dev, uint qFamIdx, SampleCount samples = SampleCount.Sample_1, uint qIndex = 0)
+ {
+ handle = NativeMethods.vkvg_device_create_multisample (instance, phy, dev, qFamIdx, qIndex, samples, false);
+ }
+ ~Device ()
+ {
+ Dispose (false);
+ }
+ #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 uint References () => NativeMethods.vkvg_device_get_reference_count (handle);
+
+ public IntPtr Handle => handle;
+
+ #region IDisposable implementation
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.vkvg_device_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
+ }
+}
+
diff --git a/Crow/src/GraphicBackends/vkvg/Enums.cs b/Crow/src/GraphicBackends/vkvg/Enums.cs
new file mode 100644
index 00000000..c76a4c3b
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Enums.cs
@@ -0,0 +1,143 @@
+// Copyright (c) 2018-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;
+
+namespace Crow.Drawing
+{
+ public enum Status
+ {
+ Success = 0,
+ NoMemory,
+ InvalidRestore,
+ InvalidPopGroup,
+ NoCurrentPoint,
+ InvalidMatrix,
+ InvalidStatus,
+ NullPointer,
+ InvalidString,
+ InvalidPathData,
+ ReadError,
+ WriteError,
+ SurfaceFinished,
+ SurfaceTypeMismatch,
+ PatternTypeMismatch,
+ InvalidContent,
+ InvalidFormat,
+ InvalidVisual,
+ FileNotFound,
+ InvalidDash
+ }
+
+ public enum Direction
+ {
+ Horizontal = 0,
+ Vertical = 1
+ }
+
+ public enum Format
+ {
+ ARGB32,
+ RGB24,
+ A8,
+ A1
+ }
+
+ public enum Extend
+ {
+ None,
+ Repeat,
+ Reflect,
+ Pad
+ }
+
+ public enum Filter
+ {
+ Fast,
+ Good,
+ Best,
+ Nearest,
+ Bilinear,
+ Gaussian,
+ }
+
+ public enum PatternType
+ {
+ Solid,
+ Surface,
+ Linear,
+ Radial,
+ Mesh,
+ RasterSource,
+ }
+
+ public enum Operator
+ {
+ Clear,
+ Source,
+ Over,
+ In,
+ Out,
+ Atop,
+
+ Dest,
+ DestOver,
+ DestIn,
+ DestOut,
+ DestAtop,
+
+ Xor,
+ Add,
+ Saturate,
+ }
+
+ public enum FontSlant
+ {
+ Normal,
+ Italic,
+ Oblique
+ }
+ public enum FontWeight
+ {
+ Normal,
+ Bold,
+ }
+
+ public enum SampleCount
+ {
+ Sample_1 = 0x00000001,
+ Sample_2 = 0x00000002,
+ Sample_4 = 0x00000004,
+ Sample_8 = 0x00000008,
+ Sample_16 = 0x00000010,
+ Sample_32 = 0x00000020,
+ Sample_64 = 0x00000040
+ }
+
+ public enum LineCap
+ {
+ Butt,
+ Round,
+ Square
+ }
+
+ public enum LineJoin
+ {
+ Miter,
+ Round,
+ Bevel
+ }
+ public enum FillRule
+ {
+ EvenOdd,
+ NonZero,
+ }
+ public enum Antialias
+ {
+ Default,
+ None,
+ Grey,
+ Subpixel,
+ }
+} \ No newline at end of file
diff --git a/Crow/src/GraphicBackends/vkvg/FontExtents.cs b/Crow/src/GraphicBackends/vkvg/FontExtents.cs
new file mode 100644
index 00000000..769b9a69
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/FontExtents.cs
@@ -0,0 +1,106 @@
+//
+// from Mono.Cairo.FontExtents.cs
+//
+// Authors: Duncan Mak (duncan@ximian.com)
+// Hisham Mardam Bey (hisham.mardambey@gmail.com)
+//
+// (C) Ximian, Inc. 2003
+//
+// This is a simplistic binding of the Cairo API to C#. All functions
+// in cairo.h are transcribed into their C# equivelants
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+// Copyright (c) 2018-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.Runtime.InteropServices;
+
+namespace Crow.Drawing
+{
+ [StructLayout (LayoutKind.Sequential)]
+ public struct FontExtents
+ {
+ float ascent;
+ float descent;
+ float height;
+ float maxXAdvance;
+ float maxYAdvance;
+
+ public float Ascent {
+ get { return ascent; }
+ set { ascent = value; }
+ }
+
+ public float Descent {
+ get { return descent; }
+ set { descent = value; }
+ }
+
+ public float Height {
+ get { return height; }
+ set { height = value; }
+ }
+
+ public float MaxXAdvance {
+ get { return maxXAdvance; }
+ set { maxXAdvance = value; }
+ }
+
+ public float MaxYAdvance {
+ get { return maxYAdvance; }
+ set { maxYAdvance = value; }
+ }
+
+ public FontExtents (float ascent, float descent, float height, float maxXAdvance, float maxYAdvance)
+ {
+ this.ascent = ascent;
+ this.descent = descent;
+ this.height = height;
+ this.maxXAdvance = maxXAdvance;
+ this.maxYAdvance = maxYAdvance;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is FontExtents)
+ return this == (FontExtents) obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) Ascent ^ (int) Descent ^ (int) Height ^ (int) MaxXAdvance ^ (int) MaxYAdvance;
+ }
+
+ public static bool operator == (FontExtents extents, FontExtents other)
+ {
+ return extents.Ascent == other.Ascent && extents.Descent == other.Descent && extents.Height == other.Height && extents.MaxXAdvance == other.MaxXAdvance && extents.MaxYAdvance == other.MaxYAdvance;
+ }
+
+ public static bool operator != (FontExtents extents, FontExtents other)
+ {
+ return !(extents == other);
+ }
+ }
+}
diff --git a/Crow/src/GraphicBackends/vkvg/Matrix.cs b/Crow/src/GraphicBackends/vkvg/Matrix.cs
new file mode 100644
index 00000000..2dc541ed
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Matrix.cs
@@ -0,0 +1,92 @@
+// Copyright (c) 2018-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;
+namespace Crow.Drawing {
+ public struct Matrix {
+ float xx; float yx;
+ float xy; float yy;
+ float x0; float y0;
+
+ public float XX { get { return xx; } set { xx = value; } }
+ public float YX { get { return yx; } set { yx = value; } }
+ public float XY { get { return xy; } set { xy = value; } }
+ public float YY { get { return yy; } set { yy = value; } }
+ public float X0 { get { return x0; } set { x0 = value; } }
+ public float Y0 { get { return y0; } set { y0 = value; } }
+
+ public static Matrix Create (float xx, float yx, float xy, float yy, float x0, float y0) {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_init (out tmp, xx, yx, xy, yy, x0, y0);
+ return tmp;
+ }
+ public static Matrix CreateTranslation (float tx, float ty) {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_init_translate (out tmp, tx, ty);
+ return tmp;
+ }
+ public static Matrix CreateRotation (float radian) {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_init_rotate (out tmp, radian);
+ return tmp;
+ }
+ public static Matrix CreateScale (float sx, float sy) {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_init_scale (out tmp, sx, sy);
+ return tmp;
+ }
+ public static Matrix Identity {
+ get {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_init_identity (out tmp);
+ return tmp;
+ }
+ }
+
+ public void Translate (float tx, float ty) {
+ Matrix tmp = this;
+ NativeMethods.vkvg_matrix_translate (ref tmp, tx, ty);
+ xx = tmp.xx; yx = tmp.yx;
+ xy = tmp.xy; yy = tmp.yy;
+ x0 = tmp.x0; y0 = tmp.y0;
+ }
+ public void Rotate (float radian) {
+ Matrix tmp = this;
+ NativeMethods.vkvg_matrix_rotate (ref tmp, radian);
+ xx = tmp.xx; yx = tmp.yx;
+ xy = tmp.xy; yy = tmp.yy;
+ x0 = tmp.x0; y0 = tmp.y0;
+ }
+ public void Scale (float sx, float sy) {
+ Matrix tmp = this;
+ NativeMethods.vkvg_matrix_scale (ref tmp, sx, sy);
+ xx = tmp.xx; yx = tmp.yx;
+ xy = tmp.xy; yy = tmp.yy;
+ x0 = tmp.x0; y0 = tmp.y0;
+ }
+ public void Invert () {
+ Matrix tmp = this;
+ NativeMethods.vkvg_matrix_invert (ref tmp);
+ xx = tmp.xx; yx = tmp.yx;
+ xy = tmp.xy; yy = tmp.yy;
+ x0 = tmp.x0; y0 = tmp.y0;
+ }
+ public void TransformDistance (ref float dx, ref float dy) {
+ NativeMethods.vkvg_matrix_transform_distance (ref this, ref dx, ref dy);
+ }
+ public void TransformPoint (ref float px, ref float py) {
+ NativeMethods.vkvg_matrix_transform_distance (ref this, ref px, ref py);
+ }
+
+ public static Matrix operator *(Matrix a, Matrix b) {
+ Matrix tmp;
+ NativeMethods.vkvg_matrix_multiply (out tmp, ref a, ref b);
+ return tmp;
+ }
+
+ public override string ToString () {
+ return string.Format ($"({xx};{yx};{xy};{yy};{x0};{y0})");
+ }
+ }
+}
diff --git a/Crow/src/GraphicBackends/vkvg/NativeMethods.cs b/Crow/src/GraphicBackends/vkvg/NativeMethods.cs
new file mode 100644
index 00000000..c87cb182
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/NativeMethods.cs
@@ -0,0 +1,275 @@
+// Copyright (c) 2018-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.Runtime.InteropServices;
+
+namespace Crow.Drawing
+{
+ internal static class NativeMethods
+ {
+ const string libvkvg = "vkvg";
+
+ #region Device
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_device_create(IntPtr instance, IntPtr phy, IntPtr dev, uint qFamIdx, uint qIndex);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_device_destroy(IntPtr device);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_device_create_multisample(IntPtr inst, IntPtr phy, IntPtr vkdev, uint qFamIdx, uint qIndex, SampleCount samples, bool deferredResolve);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_device_reference(IntPtr dev);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint vkvg_device_get_reference_count(IntPtr dev);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_device_set_dpy(IntPtr dev, int hdpy, int vdpy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_device_get_dpy(IntPtr dev, out int hdpy, out int vdpy);
+ #endregion
+
+ #region Context
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_create(IntPtr surface);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_destroy(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_flush(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_new_path(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_new_sub_path(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_close_path(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_line_to(IntPtr ctx, float x, float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_rel_line_to(IntPtr ctx, float x, float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_move_to(IntPtr ctx, float x, float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_rel_move_to(IntPtr ctx, float x, float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_arc(IntPtr ctx, float xc, float yc, float radius, float a1, float a2);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_arc_negative(IntPtr ctx, float xc, float yc, float radius, float a1, float a2);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_curve_to(IntPtr ctx, float x1, float y1, float x2, float y2, float x3, float y3);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_rel_curve_to(IntPtr ctx, float x1, float y1, float x2, float y2, float x3, float y3);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_rectangle(IntPtr ctx, float x, float y, float width, float height);
+
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_scale(IntPtr ctx, float sx, float sy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_translate(IntPtr ctx, float dx, float dy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_rotate(IntPtr ctx, float alpha);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_transform(IntPtr ctx, ref Matrix matrix);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_matrix(IntPtr ctx, ref Matrix matrix);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_get_matrix(IntPtr ctx, out Matrix matrix);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_identity_matrix(IntPtr ctx);
+
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_stroke(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_stroke_preserve(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_clip(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_clip_preserve(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_reset_clip(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_fill(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_fill_preserve(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_paint(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_source_rgba(IntPtr ctx, float r, float g, float b, float a);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_line_width(IntPtr ctx, float width);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_line_cap(IntPtr ctx, LineCap cap);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_line_join(IntPtr ctx, LineJoin join);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_operator(IntPtr ctx, Operator op);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern FillRule vkvg_get_fill_rule(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_fill_rule(IntPtr ctx, FillRule fr);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Operator vkvg_get_operator(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_source_surface(IntPtr ctx, IntPtr surf, float x, float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_source(IntPtr ctx, IntPtr pattern);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_font_extents(IntPtr ctx, out FontExtents extents);
+ [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)]
+ internal static extern void vkvg_restore(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_clear(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern float vkvg_get_line_width(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern LineCap vkvg_get_line_cap(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern LineJoin vkvg_get_line_join(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_get_source(IntPtr ctx);
+
+ [DllImport (libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_set_dash (IntPtr ctx, float[] dashes, uint dashCount, float offset);
+
+ //void vkvg_set_dash (VkvgContext ctx, const float* dashes, uint32_t num_dashes, float offset);
+ //void vkvg_get_dash (VkvgContext ctx, const float* dashes, uint32_t* num_dashes, float* offset
+
+ [DllImport (libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_reference(IntPtr ctx);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint vkvg_get_reference_count(IntPtr ctx);
+ #endregion
+
+ #region TextRun
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_text_run_create(IntPtr ctx, byte[] utf8);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_text_run_destroy(IntPtr textRun);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_show_text_run(IntPtr ctx, IntPtr textRun);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_text_run_get_extents(IntPtr textRun, out TextExtents extents);
+ #endregion
+
+ #region Pattern
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create();
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_reference(IntPtr pat);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint vkvg_pattern_get_reference_count(IntPtr pat);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create_rgba(float r, float g, float b, float a);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create_rgb(float r, float g, float b);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create_for_surface(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create_linear(float x0, float y0, float x1, float y1);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_pattern_create_radial(float cx0, float cy0, float radius0,
+ float cx1, float cy1, float radius1);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_pattern_destroy(IntPtr pat);
+
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_pattern_add_color_stop(IntPtr pat, float offset, float r, float g, float b, float a);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_pattern_set_extend(IntPtr pat, Extend extend);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_pattern_set_filter(IntPtr pat, Filter filter);
+
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Extend vkvg_pattern_get_extend(IntPtr pat);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern Filter vkvg_pattern_get_filter(IntPtr pat);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern PatternType vkvg_pattern_get_type(IntPtr pat);
+ #endregion
+
+ #region Matrices
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_init_identity(out Matrix matrix);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_init(out Matrix matrix,
+ float xx, float yx,
+ float xy, float yy,
+ float x0, float y0);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_init_translate(out Matrix matrix, float tx, float ty);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_init_scale(out Matrix matrix, float sx, float sy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_init_rotate(out Matrix matrix, float radians);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_translate(ref Matrix matrix, float tx, float ty);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_scale(ref Matrix matrix, float sx, float sy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_rotate(ref Matrix matrix, float radians);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_multiply(out Matrix result, ref Matrix a, ref Matrix b);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_transform_distance(ref Matrix matrix, ref float dx, ref float dy);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_transform_point(ref Matrix matrix, ref float x, ref float y);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_matrix_invert(ref Matrix matrix);
+ #endregion
+
+ #region Surface
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_create(IntPtr device, uint width, uint height);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_create_from_image(IntPtr dev, string filePath);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_create_from_svg(IntPtr dev, string filePath);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_create_from_svg_fragment(IntPtr dev, byte[] filePath);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_create_from_bitmap(IntPtr dev, ref byte data, uint width, uint height);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_surface_destroy(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_get_vk_image(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int vkvg_surface_get_width(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int vkvg_surface_get_height(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_surface_clear(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr vkvg_surface_reference(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern uint vkvg_surface_get_reference_count(IntPtr surf);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_surface_write_to_png(IntPtr surf, [MarshalAs(UnmanagedType.LPStr)]string path);
+ #endregion
+
+ #region NSVG
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr nsvg_load_file(IntPtr dev, string filePath);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern IntPtr nsvg_load(IntPtr dev, ref byte fragment);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void nsvg_destroy(IntPtr nsvgImage);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void nsvg_get_size(IntPtr nsvgImage, out int width, out int height);
+ [DllImport(libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_render_svg(IntPtr ctx, IntPtr nsvgImage, string subId);
+ #endregion
+ }
+}
+
diff --git a/Crow/src/GraphicBackends/vkvg/Pattern.cs b/Crow/src/GraphicBackends/vkvg/Pattern.cs
new file mode 100644
index 00000000..57401419
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Pattern.cs
@@ -0,0 +1,92 @@
+// Copyright (c) 2018-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;
+namespace Crow.Drawing
+{
+ public class Pattern : IDisposable
+ {
+
+ IntPtr handle = IntPtr.Zero;
+
+ #region CTORS & DTOR
+ protected Pattern(IntPtr handle)
+ {
+ this.handle = handle;
+ }
+ public Pattern()
+ {
+ handle = NativeMethods.vkvg_pattern_create();
+ }
+ public Pattern(float r, float g, float b)
+ {
+ handle = NativeMethods.vkvg_pattern_create_rgb(r, g, b);
+ }
+ public Pattern(float r, float g, float b, float a)
+ {
+ handle = NativeMethods.vkvg_pattern_create_rgba(r, g, b, a);
+ }
+ public Pattern(Surface surf)
+ {
+ handle = NativeMethods.vkvg_pattern_create_for_surface(surf.Handle);
+ }
+
+ ~Pattern()
+ {
+ Dispose(false);
+ }
+ #endregion
+
+ public static Pattern CreateLinearGradient(float x0, float y0, float x1, float y1)
+ {
+ return new Pattern(NativeMethods.vkvg_pattern_create_linear(x0, y0, x1, y1));
+ }
+ public static Pattern CreateRadialGradient(float cx0, float cy0, float radius0,
+ float cx1, float cy1, float radius1)
+ {
+ return new Pattern(NativeMethods.vkvg_pattern_create_radial(cx0, cy0, radius0, cx1, cy1, radius1));
+ }
+
+ public void AddReference()
+ {
+ NativeMethods.vkvg_pattern_reference(handle);
+ }
+ public uint References() => NativeMethods.vkvg_pattern_get_reference_count(handle);
+
+ public IntPtr Handle { get { return handle; } }
+
+ public Extend Extend
+ {
+ set { NativeMethods.vkvg_pattern_set_extend(handle, value); }
+ get { return NativeMethods.vkvg_pattern_get_extend(handle); }
+ }
+ public Filter Filter
+ {
+ set { NativeMethods.vkvg_pattern_set_filter(handle, value); }
+ get { return NativeMethods.vkvg_pattern_get_filter(handle); }
+ }
+
+ public void AddColorStop(float offset, float r, float g, float b, float a = 1f)
+ {
+ NativeMethods.vkvg_pattern_add_color_stop(handle, offset, r, g, b, a);
+ }
+
+ #region IDisposable implementation
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.vkvg_pattern_destroy(handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/Crow/src/GraphicBackends/vkvg/Surface.cs b/Crow/src/GraphicBackends/vkvg/Surface.cs
new file mode 100644
index 00000000..654238db
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/Surface.cs
@@ -0,0 +1,86 @@
+// Copyright (c) 2018-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;
+
+namespace Crow.Drawing
+{
+ public class Surface: IDisposable
+ {
+ IntPtr handle = IntPtr.Zero;
+ Device vkvgDev;
+
+ public Surface (Device device, int width, int height)
+ {
+ vkvgDev = device;
+ if (width <= 0 || height <= 0)
+ handle = NativeMethods.vkvg_surface_create (device.Handle, 1, 1);
+ else
+ handle = NativeMethods.vkvg_surface_create (device.Handle, (uint)width, (uint)height);
+ }
+ public Surface (Device device, Span<byte> data, int width, int heigth)
+ {
+ vkvgDev = device;
+ handle = NativeMethods.vkvg_surface_create_from_bitmap (device.Handle, ref data.GetPinnableReference(), (uint)width, (uint)heigth);
+ }
+ public Surface (Device device, string imgPath) {
+ vkvgDev = device;
+ handle = NativeMethods.vkvg_surface_create_from_image (device.Handle, imgPath);
+ }
+
+
+ Surface (IntPtr devHandle, int width, int heigth)
+ {
+ handle = NativeMethods.vkvg_surface_create (devHandle, (uint)width, (uint)heigth);
+ }
+ ~Surface ()
+ {
+ Dispose (false);
+ }
+
+ 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 uint References () => NativeMethods.vkvg_surface_get_reference_count (handle);
+
+// public Surface CreateSimilar (uint width, uint height) {
+// return new Surface (handle, width, height);
+// }
+// public Surface CreateSimilar (int width, int height) {
+// return new Surface (handle, (uint)width, (uint)height);
+// }
+
+ public void Flush () {
+ //throw new NotImplementedException ();
+ }
+
+ public void WriteToPng (string path) {
+ NativeMethods.vkvg_surface_write_to_png (handle, path);
+ }
+ public void Clear () {
+ NativeMethods.vkvg_surface_clear (handle);
+ }
+
+ #region IDisposable implementation
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.vkvg_surface_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
+ }
+}
+
diff --git a/Crow/src/GraphicBackends/vkvg/SvgHandle.cs b/Crow/src/GraphicBackends/vkvg/SvgHandle.cs
new file mode 100644
index 00000000..d923d89f
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/SvgHandle.cs
@@ -0,0 +1,42 @@
+//Copyright GPL2
+using System;
+
+namespace Crow.Drawing {
+
+
+ public sealed class SvgHandle : IDisposable {
+
+ public IntPtr Raw;
+
+ public SvgHandle (Device dev, Span<byte> bytes)
+ {
+ /*int size = svgFragment.Length * 4 + 1;
+ Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ int encodedBytes = Crow.Text.Encoding.ToUtf8 (svgFragment, bytes);
+ bytes[encodedBytes] = 0;*/
+ Raw = NativeMethods.nsvg_load (dev.Handle, ref bytes.GetPinnableReference());
+ }
+ public SvgHandle (Device dev, string file_name)
+ {
+ Raw = NativeMethods.nsvg_load_file (dev.Handle, file_name);
+ }
+
+ public void Render(Context cr) =>
+ cr.RenderSvg (Raw);
+
+ public void Render (Context cr, string id) =>
+ cr.RenderSvg (Raw, id);
+
+ public Size Dimensions {
+ get {
+ NativeMethods.nsvg_get_size (Raw, out int w, out int h);
+ return new Size (w, h);
+ }
+ }
+
+ public void Dispose() {
+ NativeMethods.nsvg_destroy (Raw);
+ }
+
+ }
+}
diff --git a/Crow/src/GraphicBackends/vkvg/TextExtents.cs b/Crow/src/GraphicBackends/vkvg/TextExtents.cs
new file mode 100644
index 00000000..bd320e40
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/TextExtents.cs
@@ -0,0 +1,72 @@
+// Copyright (c) 2018-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.Runtime.InteropServices;
+
+namespace Crow.Drawing
+{
+ [StructLayout (LayoutKind.Sequential)]
+ public struct TextExtents
+ {
+ float xbearing;
+ float ybearing;
+ float width;
+ float height;
+ float xadvance;
+ float yadvance;
+
+ public float XBearing {
+ get { return xbearing; }
+ set { xbearing = value; }
+ }
+
+ public float YBearing {
+ get { return ybearing; }
+ set { ybearing = value; }
+ }
+
+ public float Width {
+ get { return width; }
+ set { width = value; }
+ }
+
+ public float Height {
+ get { return height; }
+ set { height = value; }
+ }
+
+ public float XAdvance {
+ get { return xadvance; }
+ set { xadvance = value; }
+ }
+
+ public float YAdvance {
+ get { return yadvance; }
+ set { yadvance = value; }
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj is TextExtents)
+ return this == (TextExtents)obj;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int)XBearing ^ (int)YBearing ^ (int)Width ^ (int)Height ^ (int)XAdvance ^ (int)YAdvance;
+ }
+
+ public static bool operator == (TextExtents extents, TextExtents other)
+ {
+ return extents.XBearing == other.XBearing && extents.YBearing == other.YBearing && extents.Width == other.Width && extents.Height == other.Height && extents.XAdvance == other.XAdvance && extents.YAdvance == other.YAdvance;
+ }
+
+ public static bool operator != (TextExtents extents, TextExtents other)
+ {
+ return !(extents == other);
+ }
+ }
+}
diff --git a/Crow/src/GraphicBackends/vkvg/TextRun.cs b/Crow/src/GraphicBackends/vkvg/TextRun.cs
new file mode 100644
index 00000000..f4553692
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/TextRun.cs
@@ -0,0 +1,54 @@
+// Copyright (c) 2018-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;
+namespace Crow.Drawing {
+ public class TextRun : IDisposable {
+
+ IntPtr handle = IntPtr.Zero;
+
+ #region CTORS & DTOR
+ protected TextRun(IntPtr handle) {
+ this.handle = handle;
+ }
+ public TextRun(string text) {
+ handle = NativeMethods.vkvg_text_run_create (handle, Context.TerminateUtf8(text));
+ }
+
+ ~TextRun() {
+ Dispose (false);
+ }
+ #endregion
+
+ //public void AddReference () {
+ // NativeMethods.vkvg_pattern_reference (handle);
+ //}
+ //public uint References () => NativeMethods.vkvg_pattern_get_reference_count (handle);
+
+ public IntPtr Handle { get { return handle; } }
+
+ public TextExtents Extents {
+ get {
+ TextExtents extents;
+ NativeMethods.vkvg_text_run_get_extents (handle, out extents);
+ return extents;
+ }
+ }
+
+ #region IDisposable implementation
+ public void Dispose () {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing) {
+ if (!disposing || handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.vkvg_text_run_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/Crow/src/GraphicBackends/vkvg/VulkanContext.cs b/Crow/src/GraphicBackends/vkvg/VulkanContext.cs
new file mode 100644
index 00000000..e27f3694
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/VulkanContext.cs
@@ -0,0 +1,207 @@
+// Copyright (c) 2019-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;
+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 Crow.Drawing {
+ /// <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 => new string[] { Ext.I.VK_EXT_debug_utils };
+
+ string[] EnabledDeviceExtensions => new string[] { Ext.D.VK_KHR_swapchain };
+
+ uint width, height;
+ public void WaitIdle() => dev.WaitIdle ();
+ public VulkanContext (IntPtr hWin, uint _width, uint _height, bool vsync = false) {
+ this.hWin = hWin;
+ //Instance.VALIDATION = true;
+ //Instance.RENDER_DOC_CAPTURE = true;
+
+ SwapChain.IMAGES_USAGE = VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransferDst;
+ SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm;
+
+ 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 Crow.Drawing.Device CreateVkvgDevice () =>
+ new Crow.Drawing.Device (instance.Handle, phy.Handle, dev.VkDev.Handle, presentQueue.qFamIndex, SampleCount.Sample_8);
+
+ internal vke.Image blitSource;
+
+ public void BuildBlitCommand (Crow.Drawing.Surface surf) {
+ //Console.WriteLine ($"build blit w:{width} h:{height}");
+ cmdPool.Reset();
+
+ blitSource = new vke.Image (dev, new VkImage((ulong)surf.VkImage.ToInt64()), Vulkan.VkFormat.B8g8r8a8Unorm,
+ 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.Undefined, VkImageLayout.TransferDstOptimal,
+ VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.Transfer);
+
+ blitSource.SetLayout (cmd, VkImageAspectFlags.Color,
+ VkImageLayout.ColorAttachmentOptimal, VkImageLayout.TransferSrcOptimal,
+ VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.Transfer);
+
+ blitSource.BlitTo (cmd, blitDest, VkFilter.Nearest);
+
+ blitDest.SetLayout (cmd, VkImageAspectFlags.Color,
+ VkImageLayout.TransferDstOptimal, VkImageLayout.PresentSrcKHR,
+ VkPipelineStageFlags.Transfer, VkPipelineStageFlags.BottomOfPipe);
+
+ blitSource.SetLayout (cmd, VkImageAspectFlags.Color,
+ VkImageLayout.TransferSrcOptimal, VkImageLayout.ColorAttachmentOptimal,
+ VkPipelineStageFlags.Transfer, VkPipelineStageFlags.ColorAttachmentOutput);
+
+ cmd.End ();
+ }
+ }
+ public void WaitAndResetDrawFence () {
+ drawFence.Wait ();
+ drawFence.Reset ();
+ }
+ /// <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 bool render () {
+ WaitIdle();
+
+ int idx = swapChain.GetNextImage ();
+ if (idx < 0) {
+ width = swapChain.Width;
+ height = swapChain.Height;
+ //Console.WriteLine ($"get next image failed w:{width} h:{height}");
+ return false;
+ }
+
+ if (cmds[idx] == null)
+ return false;
+ WaitAndResetDrawFence();
+
+ presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence);
+ presentQueue.Present (swapChain, drawComplete[idx]);
+
+ WaitIdle();
+ return true;
+ }
+
+ #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/FontOptions.cs b/Crow/src/GraphicBackends/vkvg/tmp/FontOptions.cs
new file mode 100644
index 00000000..1d9764fb
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/tmp/FontOptions.cs
@@ -0,0 +1,74 @@
+//from Mono.Cairo
+//fake FontOptions
+
+using System;
+
+namespace Crow.Drawing
+{
+ public enum SubpixelOrder
+ {
+ Default,
+ Rgb,
+ Bgr,
+ Vrgb,
+ Vbgr,
+ }
+ public enum HintMetrics
+ {
+ Default,
+ Off,
+ On,
+ }
+ public enum HintStyle
+ {
+ Default,
+ None,
+ Slight,
+ Medium,
+ Full,
+ }
+ public class FontOptions : IDisposable
+ {
+ public FontOptions () { }
+
+
+ public FontOptions Copy () => default;
+
+
+ public IntPtr Handle {
+ get ;
+ }
+
+
+ public void Merge (FontOptions other)
+ {
+ }
+
+ public void Dispose() {}
+
+ public Antialias Antialias {
+ get ;
+ set ;
+ }
+
+ public HintMetrics HintMetrics {
+ get ;
+ set ;
+ }
+
+ public HintStyle HintStyle {
+ get ;
+ set ;
+ }
+
+ public Status Status {
+ get ;
+ }
+
+ public SubpixelOrder SubpixelOrder {
+ get ;
+ set ;
+ }
+ }
+}
+
diff --git a/Crow/src/GraphicBackends/vkvg/tmp/Region.cs b/Crow/src/GraphicBackends/vkvg/tmp/Region.cs
new file mode 100644
index 00000000..83dc7f2b
--- /dev/null
+++ b/Crow/src/GraphicBackends/vkvg/tmp/Region.cs
@@ -0,0 +1,133 @@
+// 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 System;
+using Crow.Drawing;
+
+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 (r == default)
+ return;
+ 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 OverlapOut (Rectangle r) {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(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) {
+ /*if (r == default)
+ System.Diagnostics.Debugger.Break ();*/
+ 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()
+ {
+
+ }
+ }
+}
diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs
index dece83e2..a152e472 100644
--- a/Crow/src/Interface.cs
+++ b/Crow/src/Interface.cs
@@ -13,8 +13,9 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
-using Crow.Cairo;
+
using Crow.IML;
+using Crow.Drawing;
using Glfw;
using Path = System.IO.Path;
@@ -146,12 +147,17 @@ namespace Crow
PerformanceMeasure.InitMeasures ();
+#if VKVG
+ //force single threaded interface for vkvg until multithreading in vkvg is ok
+ startUIThread = false;
+#endif
+
if (startUIThread) {
Thread t = new Thread (InterfaceThread) {
IsBackground = true
};
t.Start ();
- }
+ }
}
#endregion
@@ -179,7 +185,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 ();
@@ -195,6 +205,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;
@@ -216,6 +232,7 @@ namespace Crow
case PlatformID.WinCE:
throw new PlatformNotSupportedException ("Unable to create cairo surface.");
}
+#endif
}
public void SetWindowIcon (string path) {
@@ -244,8 +261,8 @@ namespace Crow
image [i + 2] = Marshal.ReadByte (stbi.Handle, i);
image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3);
}
- Glfw.Image icon = new Glfw.Image (stbi.Width, stbi.Height, image);
- Glfw3.setWindowIcon (hWin, 1, ref icon);
+ Glfw.Image icon = new Glfw.Image ((uint)stbi.Width, (uint)stbi.Height, image);
+ Glfw3.SetWindowIcon (hWin, 1, ref icon);
icon.Dispose();
}
#endif
@@ -367,7 +384,12 @@ namespace Crow
Terminate ();
}
public virtual void Terminate () {}
- public virtual void UpdateFrame () { Thread.Sleep (1); }
+ public virtual void UpdateFrame () {
+#if VKVG
+ Update ();
+ Thread.Sleep (UPDATE_INTERVAL);
+#endif
+ }
public virtual void Quit () => Glfw3.SetWindowShouldClose (hWin, 1);
@@ -692,7 +714,7 @@ namespace Crow
string resId = $"#{pic.Substring (path.Length + 1).Replace (Path.DirectorySeparatorChar, '.')}";
using (Stream s = new FileStream (pic, FileMode.Open, FileAccess.Read)) {
if (resId.EndsWith (".svg", StringComparison.OrdinalIgnoreCase))
- sharedPictures[resId] = SvgPicture.CreateSharedPicture (s);
+ sharedPictures[resId] = SvgPicture.CreateSharedPicture (this, s);
else
sharedPictures[resId] = BmpPicture.CreateSharedPicture (s);
}
@@ -1024,11 +1046,25 @@ namespace Crow
clippingRegistration ();
- if (ctx == null) {
- using (ctx = new Context (surf))
+
+ if (!clipping.IsEmpty) {
+ if (ctx == null) {
+ using (ctx = new Context (surf))
+ processDrawing (ctx);
+ }else
processDrawing (ctx);
- }else
- processDrawing (ctx);
+ }
+
+#if VKVG
+ if (IsDirty) {
+ if (vkCtx.render ())
+ IsDirty = false;
+ else {
+ resizeVulkanContext();
+ }
+ }
+#endif
+
} finally {
PerformanceMeasure.End (PerformanceMeasure.Kind.Update);
@@ -1039,6 +1075,19 @@ namespace Crow
PerformanceMeasure.Notify ();
}
+ void resizeVulkanContext () {
+ vkCtx.WaitIdle();
+ vkCtx.blitSource?.Dispose ();
+ surf?.Dispose ();
+ surf = new Surface (vkvgDevice, clientRectangle.Width, clientRectangle.Height);
+ vkCtx.BuildBlitCommand (surf);
+ vkCtx.WaitIdle();
+ foreach (Widget g in GraphicTree)
+ g.RegisterForLayouting (LayoutingType.All);
+
+ registerRefreshClientRectangle ();
+
+ }
/// <summary>Layouting loop, this is the first step of the udpate and process registered
/// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which
/// trigger an enqueue for the next Update Cycle</summary>
@@ -1095,7 +1144,7 @@ namespace Crow
ctx.ClipPreserve ();
ctx.Operator = Operator.Clear;
- ctx.Fill ();
+ ctx.Fill ();
ctx.Operator = Operator.Over;
}
bool solidBackground = false;
@@ -1113,25 +1162,29 @@ namespace Crow
/// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be
/// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary>
protected virtual void processDrawing(Context ctx){
-
DbgLogger.StartEvent (DbgEvtType.ProcessDrawing);
if (DragImage != null)
clipping.UnionRectangle(DragImageBounds);
- if (!clipping.IsEmpty) {
+
PerformanceMeasure.Begin (PerformanceMeasure.Kind.Drawing);
+#if VKVG
+ clear (ctx);
+#else
ctx.PushGroup ();
if (SolidBackground)
clear (ctx);
+ ctx.Flush();
+#endif
for (int i = GraphicTree.Count -1; i >= 0 ; i--){
Widget p = GraphicTree[i];
if (!p.IsVisible)
continue;
- if (clipping.Contains (p.Slot) == RegionOverlap.Out)
+ if (clipping.OverlapOut (p.Slot))
continue;
//ctx.Save ();
@@ -1158,12 +1211,18 @@ namespace Crow
#if DEBUG_CLIP_RECTANGLE
ctx.LineWidth = 1;
- ctx.SetSource(1,0,0,0.5);
+ ctx.SetSource(1,1,0,0.5);
for (int i = 0; i < clipping.NumRectangles; i++)
ctx.Rectangle(clipping.GetRectangle(i));
ctx.Stroke ();
+
#endif
+#if VKVG
+ ctx.Flush();
+ //vkCtx.render ();
+ //vkCtx.WaitIdle();
+#else
ctx.PopGroupToSource ();
if (!SolidBackground)
@@ -1172,15 +1231,16 @@ namespace Crow
ctx.Paint ();
surf.Flush ();
-
+#endif
clipping.Reset ();
PerformanceMeasure.End (PerformanceMeasure.Kind.Drawing);
IsDirty = true;
- }
-
+
+#if !VKVG
drawTextCursor (ctx);
+#endif
debugHighlightFocus (ctx);
@@ -1360,6 +1420,9 @@ namespace Crow
lock (UpdateMutex) {
clientRectangle = bounds;
+#if VKVG
+
+#else
switch (Environment.OSVersion.Platform) {
case PlatformID.MacOSX:
break;
@@ -1381,11 +1444,11 @@ namespace Crow
case PlatformID.WinCE:
throw new PlatformNotSupportedException ("Unable to create cairo surface.");
}
-
foreach (Widget g in GraphicTree)
g.RegisterForLayouting (LayoutingType.All);
registerRefreshClientRectangle ();
+#endif
}
}
diff --git a/Crow/src/Mono.Cairo b/Crow/src/Mono.Cairo
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/Crow/src/Mono.Cairo
diff --git a/Crow/src/Text/IEditableTextWidget.cs b/Crow/src/Text/IEditableTextWidget.cs
index 19f3ebd0..d72f1de7 100644
--- a/Crow/src/Text/IEditableTextWidget.cs
+++ b/Crow/src/Text/IEditableTextWidget.cs
@@ -2,7 +2,7 @@
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Widgets/Border.cs b/Crow/src/Widgets/Border.cs
index c702d9ac..47358100 100644
--- a/Crow/src/Widgets/Border.cs
+++ b/Crow/src/Widgets/Border.cs
@@ -3,7 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
using System.ComponentModel;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
@@ -104,15 +104,15 @@ namespace Crow
{
drawborder2 (gr);
- gr.Save ();
+ /*gr.Save ();
if (ClipToClientRect) {
CairoHelpers.CairoRectangle (gr, ClientRectangle, Math.Max (0.0, CornerRadius - Margin));
gr.Clip ();
- }
+ }*/
+
+ child?.Paint (gr);
- if (child != null)
- child.Paint (gr);
- gr.Restore ();
+ //gr.Restore ();
}
void drawborder2(Context gr){
Rectangle rBack = new Rectangle (Slot.Size);
diff --git a/Crow/src/Widgets/CircleMeter.cs b/Crow/src/Widgets/CircleMeter.cs
index 6e3e67c6..e076ca66 100644
--- a/Crow/src/Widgets/CircleMeter.cs
+++ b/Crow/src/Widgets/CircleMeter.cs
@@ -4,11 +4,10 @@
using System;
using System.ComponentModel;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow {
-
-public class CircleMeter : Gauge {
+ public class CircleMeter : Gauge {
#region CTOR
protected CircleMeter () {}
public CircleMeter (Interface iface, string style = null) : base (iface, style) { }
diff --git a/Crow/src/Widgets/ColorSlider.cs b/Crow/src/Widgets/ColorSlider.cs
index 9ac4b8a0..183686da 100644
--- a/Crow/src/Widgets/ColorSlider.cs
+++ b/Crow/src/Widgets/ColorSlider.cs
@@ -1,11 +1,12 @@
-// Copyright (c) 2013-2019 Bruyère Jean-Philippe jp_bruyere@hotmail.com
+// Copyright (c) 2013-2021 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.ComponentModel;
-using Crow.Cairo;
+
using Glfw;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Widgets/DockWindow.cs b/Crow/src/Widgets/DockWindow.cs
index 7f36dad4..0edccaa5 100644
--- a/Crow/src/Widgets/DockWindow.cs
+++ b/Crow/src/Widgets/DockWindow.cs
@@ -4,7 +4,7 @@
using System;
using System.Xml.Serialization;
-using Crow.Cairo;
+
using Glfw;
namespace Crow
@@ -198,8 +198,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);
@@ -207,7 +207,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) {
diff --git a/Crow/src/Widgets/Expandable.cs b/Crow/src/Widgets/Expandable.cs
index d63249bb..1e334c2e 100644
--- a/Crow/src/Widgets/Expandable.cs
+++ b/Crow/src/Widgets/Expandable.cs
@@ -49,7 +49,7 @@ namespace Crow
public override void OnDataSourceChanged(object sender, DataSourceChangeEventArgs e)
{
base.OnDataSourceChanged(sender, e);
- NotifyValueChanged ("IsExpandable", IsExpandable);
+ //NotifyValueChanged ("IsExpandable", IsExpandable);
}
/// <summary>
diff --git a/Crow/src/Widgets/Gauge.cs b/Crow/src/Widgets/Gauge.cs
index 7384453e..c3c84919 100644
--- a/Crow/src/Widgets/Gauge.cs
+++ b/Crow/src/Widgets/Gauge.cs
@@ -4,7 +4,8 @@
using System;
using System.ComponentModel;
-using Crow.Cairo;
+
+using Crow.Drawing;
namespace Crow {
public class Gauge : Widget
diff --git a/Crow/src/Widgets/GraduatedSlider.cs b/Crow/src/Widgets/GraduatedSlider.cs
index 01b8b4cb..e041cfb2 100644
--- a/Crow/src/Widgets/GraduatedSlider.cs
+++ b/Crow/src/Widgets/GraduatedSlider.cs
@@ -2,7 +2,7 @@
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using Crow.Cairo;
+
namespace Crow
{
diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs
index e771426e..33e1b4c1 100644
--- a/Crow/src/Widgets/Group.cs
+++ b/Crow/src/Widgets/Group.cs
@@ -5,7 +5,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using Crow.Cairo;
+
using System.Threading;
using static Crow.Logger;
diff --git a/Crow/src/Widgets/GroupBase.cs b/Crow/src/Widgets/GroupBase.cs
index 752c98de..13d99f0a 100644
--- a/Crow/src/Widgets/GroupBase.cs
+++ b/Crow/src/Widgets/GroupBase.cs
@@ -5,10 +5,11 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using Crow.Cairo;
+
using System.Threading;
using static Crow.Logger;
+using Crow.Drawing;
namespace Crow
{
@@ -255,7 +256,7 @@ namespace Crow
gr.Rectangle(Clipping.GetRectangle(i));
gr.ClipPreserve();
gr.Operator = Operator.Clear;
- gr.Fill();
+ gr.Fill();
gr.Operator = Operator.Over;
base.onDraw (gr);
@@ -270,7 +271,7 @@ namespace Crow
foreach (Widget c in Children) {
if (!c.IsVisible)
continue;
- if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out)
+ if (Clipping.OverlapOut (c.Slot + ClientRectangle.Position))
continue;
c.Paint (gr);
}
diff --git a/Crow/src/Widgets/HueSelector.cs b/Crow/src/Widgets/HueSelector.cs
index 64f8217e..c4d3172a 100644
--- a/Crow/src/Widgets/HueSelector.cs
+++ b/Crow/src/Widgets/HueSelector.cs
@@ -1,33 +1,12 @@
-//
-// HueSelector.cs
+// Copyright (c) 2013-2021 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
-// Author:
-// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-// Copyright (c) 2013-2017 Jean-Philippe Bruyère
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
+// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
using System.Xml.Serialization;
using System.ComponentModel;
-using Crow.Cairo;
+
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Widgets/Image.cs b/Crow/src/Widgets/Image.cs
index 6969541f..0473893b 100644
--- a/Crow/src/Widgets/Image.cs
+++ b/Crow/src/Widgets/Image.cs
@@ -1,13 +1,14 @@
-// Copyright (c) 2013-2019 Jean-Philippe Bruyère jp_bruyere@hotmail.com
+// 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)
using System;
-using Crow.Cairo;
+
using System.Xml.Serialization;
using System.ComponentModel;
using System.Diagnostics;
+using Crow.Drawing;
namespace Crow
{
@@ -161,6 +162,8 @@ namespace Crow
{
if (_pic == null)
return 2 * Margin;
+ if (!_pic.IsLoaded)
+ _pic.load (IFace);
//_pic = "#Crow.Images.Icons.IconAlerte.svg";
//TODO:take scalling in account
if (lt == LayoutingType.Width)
diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs
index c2c68648..e01fe269 100644
--- a/Crow/src/Widgets/Label.cs
+++ b/Crow/src/Widgets/Label.cs
@@ -4,9 +4,10 @@
using System;
using System.Linq;
-using Crow.Cairo;
+
using System.ComponentModel;
using Glfw;
+using Crow.Drawing;
using Crow.Text;
namespace Crow
@@ -637,6 +638,8 @@ namespace Crow
protected override void onDraw (Context gr)
{
+ DbgLogger.StartEvent(DbgEvtType.GODraw, this);
+
base.onDraw (gr);
setFontForContext (gr);
@@ -657,6 +660,8 @@ namespace Crow
if (ClipToClientRect)
gr.Restore ();
+
+ DbgLogger.EndEvent (DbgEvtType.GODraw);
}
#endregion
diff --git a/Crow/src/Widgets/OldLabel.cs b/Crow/src/Widgets/OldLabel.cs
deleted file mode 100644
index 17179ae3..00000000
--- a/Crow/src/Widgets/OldLabel.cs
+++ /dev/null
@@ -1,846 +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;
-using Crow.Cairo;
-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
index c236bf4b..00000000
--- a/Crow/src/Widgets/OldTextBox.cs
+++ /dev/null
@@ -1,186 +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)
-
-using Crow.Cairo;
-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
- }
-}
diff --git a/Crow/src/Widgets/PrivateContainer.cs b/Crow/src/Widgets/PrivateContainer.cs
index d7d269b4..b08e1857 100644
--- a/Crow/src/Widgets/PrivateContainer.cs
+++ b/Crow/src/Widgets/PrivateContainer.cs
@@ -3,7 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using Crow.Cairo;
+using Crow.Drawing;
using static Crow.Logger;
namespace Crow
{
@@ -220,7 +220,7 @@ namespace Crow
gr.Rectangle(Clipping.GetRectangle(i));
gr.ClipPreserve();
gr.Operator = Operator.Clear;
- gr.Fill();
+ gr.Fill();
gr.Operator = Operator.Over;
onDraw (gr);
diff --git a/Crow/src/Widgets/ProgressBar.cs b/Crow/src/Widgets/ProgressBar.cs
index ca9a1a3d..bcf9a5f9 100644
--- a/Crow/src/Widgets/ProgressBar.cs
+++ b/Crow/src/Widgets/ProgressBar.cs
@@ -3,7 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System.ComponentModel;
-using Crow.Cairo;
+
namespace Crow
{
diff --git a/Crow/src/Widgets/SaturationValueSelector.cs b/Crow/src/Widgets/SaturationValueSelector.cs
index c56dd30c..6fc23522 100644
--- a/Crow/src/Widgets/SaturationValueSelector.cs
+++ b/Crow/src/Widgets/SaturationValueSelector.cs
@@ -3,7 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Widgets/Scroller.cs b/Crow/src/Widgets/Scroller.cs
index 314a7503..3a386e2d 100644
--- a/Crow/src/Widgets/Scroller.cs
+++ b/Crow/src/Widgets/Scroller.cs
@@ -1,10 +1,10 @@
-// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// 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)
using System;
using System.ComponentModel;
-using Crow.Cairo;
+using Crow.Drawing;
using Glfw;
namespace Crow
@@ -187,8 +187,9 @@ namespace Crow
Background.SetAsSource (IFace, gr, rBack);
CairoHelpers.CairoRectangle(gr,rBack, CornerRadius);
gr.Fill ();
-
+
gr.Save ();
+
if (ClipToClientRect) {
//clip to scrolled client zone
CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
@@ -196,8 +197,12 @@ namespace Crow
}
gr.Translate (-ScrollX, -ScrollY);
+
if (child != null)
child.Paint (gr);
+
+ //gr.Translate (ScrollX, ScrollY);
+
gr.Restore ();
}
diff --git a/Crow/src/Widgets/ScrollingStack.cs b/Crow/src/Widgets/ScrollingStack.cs
index b00bb211..6bda175c 100644
--- a/Crow/src/Widgets/ScrollingStack.cs
+++ b/Crow/src/Widgets/ScrollingStack.cs
@@ -4,7 +4,7 @@
using System;
using System.ComponentModel;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow {
public class ScrollingStack : GenericStack {
diff --git a/Crow/src/Widgets/Shape.cs b/Crow/src/Widgets/Shape.cs
index dd8fefdf..a70a3a9e 100644
--- a/Crow/src/Widgets/Shape.cs
+++ b/Crow/src/Widgets/Shape.cs
@@ -6,7 +6,7 @@ using System;
using System.ComponentModel;
using System.IO;
using System.Text;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
@@ -219,7 +219,8 @@ namespace Crow
widthRatio = heightRatio;
}
- gr.Save ();
+ Matrix m = gr.Matrix;
+ //gr.Save ();
gr.Translate (cr.Left, cr.Top);
gr.Scale (widthRatio, heightRatio);
@@ -231,7 +232,8 @@ namespace Crow
using (PathParser parser = new PathParser (path))
parser.Draw (gr);
- gr.Restore ();
+ //gr.Restore ();
+ gr.Matrix = m;
}
diff --git a/Crow/src/Widgets/Slider.cs b/Crow/src/Widgets/Slider.cs
index d89ae705..8e197fda 100644
--- a/Crow/src/Widgets/Slider.cs
+++ b/Crow/src/Widgets/Slider.cs
@@ -2,7 +2,7 @@
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using Crow.Cairo;
+
using System;
using System.ComponentModel;
diff --git a/Crow/src/Widgets/TabView.cs b/Crow/src/Widgets/TabView.cs
index 8872b92b..d8108695 100644
--- a/Crow/src/Widgets/TabView.cs
+++ b/Crow/src/Widgets/TabView.cs
@@ -4,7 +4,7 @@
using System;
using System.ComponentModel;
-using Crow.Cairo;
+
using System.Linq;
namespace Crow
diff --git a/Crow/src/Widgets/Table.cs b/Crow/src/Widgets/Table.cs
index a683dd78..c712cb3d 100644
--- a/Crow/src/Widgets/Table.cs
+++ b/Crow/src/Widgets/Table.cs
@@ -4,7 +4,7 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
diff --git a/Crow/src/Widgets/TableRow copy.cs b/Crow/src/Widgets/TableRow copy.cs
index 2184d486..1579af7a 100644
--- a/Crow/src/Widgets/TableRow copy.cs
+++ b/Crow/src/Widgets/TableRow copy.cs
@@ -4,7 +4,7 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Crow.Cairo;
+
using Glfw;
namespace Crow
diff --git a/Crow/src/Widgets/TableRow.cs b/Crow/src/Widgets/TableRow.cs
index fbb0e7c4..2c6db331 100644
--- a/Crow/src/Widgets/TableRow.cs
+++ b/Crow/src/Widgets/TableRow.cs
@@ -4,7 +4,7 @@
using System;
using System.ComponentModel;
using System.Linq;
-using Crow.Cairo;
+
using Glfw;
namespace Crow
diff --git a/Crow/src/Widgets/TemplatedControl.cs b/Crow/src/Widgets/TemplatedControl.cs
index 3d0d4258..822ac5d0 100644
--- a/Crow/src/Widgets/TemplatedControl.cs
+++ b/Crow/src/Widgets/TemplatedControl.cs
@@ -5,9 +5,7 @@
using System;
using System.ComponentModel;
using System.IO;
-using System.Reflection;
-using System.Xml;
-using Crow.Cairo;
+using Crow.Drawing;
namespace Crow
{
@@ -82,26 +80,26 @@ namespace Crow
//public override T FindByType<T> () => this is TemplatedControl tg ? tg : default (T);
public Widget FindByNameInTemplate (string nameToFind) => child?.FindByName (nameToFind);
/// <summary>
- ///onDraw is overrided to prevent default drawing of background, template top container
+ ///onDraw is overriden to prevent default drawing of background, template top container
///may have a binding to root background or a fixed one.
///this allow applying root background to random template's component
/// </summary>
/// <param name="gr">Backend context</param>
protected override void onDraw (Context gr)
{
- DbgLogger.StartEvent (DbgEvtType.GODraw, this);
-
- gr.Save ();
+ DbgLogger.StartEvent (DbgEvtType.GODraw, this);
if (ClipToClientRect) {
//clip to client zone
+ gr.Save ();
CairoHelpers.CairoRectangle (gr, ClientRectangle, CornerRadius);
gr.Clip ();
}
child?.Paint (gr);
- gr.Restore ();
+ if (ClipToClientRect)
+ gr.Restore ();
DbgLogger.EndEvent (DbgEvtType.GODraw);
}
diff --git a/Crow/src/Widgets/TemplatedGroup.cs b/Crow/src/Widgets/TemplatedGroup.cs
index 2ebede8e..11a206e9 100644
--- a/Crow/src/Widgets/TemplatedGroup.cs
+++ b/Crow/src/Widgets/TemplatedGroup.cs
@@ -8,7 +8,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading;
-using Crow.Cairo;
+
using Crow.IML;
namespace Crow {
diff --git a/Crow/src/Widgets/TestCairoPatch.cs b/Crow/src/Widgets/TestCairoPatch.cs
deleted file mode 100644
index 99230a05..00000000
--- a/Crow/src/Widgets/TestCairoPatch.cs
+++ /dev/null
@@ -1,127 +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 Crow.Cairo;
-
-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/TextBox.cs b/Crow/src/Widgets/TextBox.cs
index 8bce1322..aebcc071 100644
--- a/Crow/src/Widgets/TextBox.cs
+++ b/Crow/src/Widgets/TextBox.cs
@@ -2,12 +2,13 @@
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using Crow.Cairo;
-using Crow.Text;
-using Glfw;
using System;
using System.ComponentModel;
+using Crow.Text;
+using Crow.Drawing;
+using Glfw;
+
namespace Crow
{
public class TextBox : Label
diff --git a/Crow/src/Widgets/TextRun.cs b/Crow/src/Widgets/TextRun.cs
deleted file mode 100644
index d118974f..00000000
--- a/Crow/src/Widgets/TextRun.cs
+++ /dev/null
@@ -1,278 +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;
-using Crow.Cairo;
-
-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
index 1a2d1375..00000000
--- a/Crow/src/Widgets/Trend.cs
+++ /dev/null
@@ -1,164 +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;
-using Crow.Cairo;
-
-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 ();
- }
- }
-}
-
diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs
index d595e164..245dddf3 100644
--- a/Crow/src/Widgets/Widget.cs
+++ b/Crow/src/Widgets/Widget.cs
@@ -8,9 +8,10 @@ using System.ComponentModel;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
-using Crow.Cairo;
+
using System.Diagnostics;
using Crow.IML;
+using Crow.Drawing;
using System.Threading;
using Glfw;
using System.Linq;
@@ -118,7 +119,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;
@@ -1886,10 +1891,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
@@ -1919,10 +1930,19 @@ namespace Crow
else if (LastPaintedSlot.Width != Slot.Width || LastPaintedSlot.Height != Slot.Height)
bmp.SetSize (Slot.Width, Slot.Height);*/
bmp?.Dispose ();
+#if (VKVG)
+ DbgLogger.StartEvent (DbgEvtType.GOCreateSurface, this);
+ bmp = new Surface (IFace.vkvgDevice, Slot.Width, Slot.Height);
+ DbgLogger.EndEvent (DbgEvtType.GOCreateSurface);
+ //bmp.Clear();
+#else
bmp = IFace.surf.CreateSimilar (Content.ColorAlpha, Slot.Width, Slot.Height);
+#endif
//bmp = new ImageSurface(Format.Argb32, Slot.Width, Slot.Height);
+ DbgLogger.StartEvent (DbgEvtType.GOCreateContext, this);
using (Context gr = new Context (bmp)) {
+ DbgLogger.EndEvent (DbgEvtType.GOCreateContext);
gr.Antialias = Interface.Antialias;
onDraw (gr);
}
@@ -1940,8 +1960,9 @@ namespace Crow
ctx.Operator = Operator.Over;
}
- ctx.SetSource (bmp, rb.X, rb.Y);
+ ctx.SetSource (bmp, rb.X, rb.Y);
ctx.Paint ();
+ ctx.Flush ();
DbgLogger.EndEvent(DbgEvtType.GOPaintCache);
}
protected virtual void UpdateCache(Context ctx){
@@ -1991,13 +2012,15 @@ namespace Crow
paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
} else {
Rectangle rb = Slot + Parent.ClientRectangle.Position;
- ctx.Save ();
+ //ctx.Save ();
ctx.Translate (rb.X, rb.Y);
onDraw (ctx);
- ctx.Restore ();
+ ctx.Translate (-rb.X, -rb.Y);
+
+ //ctx.Restore ();
if (!IsEnabled)
paintDisabled (ctx, rb);
diff --git a/Crow/src/rsvg/DimensionData.cs b/Crow/src/rsvg/DimensionData.cs
deleted file mode 100644
index 66aab91c..00000000
--- a/Crow/src/rsvg/DimensionData.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-//Copyright GPL2
-namespace Rsvg {
-
- using System;
- using System.Collections;
- using System.Runtime.InteropServices;
-
- [StructLayout(LayoutKind.Sequential)]
- public struct DimensionData {
-
- public int Width;
- public int Height;
- public double Em;
- public double Ex;
-
- public static Rsvg.DimensionData Zero = new Rsvg.DimensionData ();
-
- public static Rsvg.DimensionData New(IntPtr raw) {
- if (raw == IntPtr.Zero)
- return Rsvg.DimensionData.Zero;
- return (Rsvg.DimensionData) Marshal.PtrToStructure (raw, typeof (Rsvg.DimensionData));
- }
- }
-}
diff --git a/Directory.Build.props b/Directory.Build.props
index 11fcc004..917e7dfc 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,8 +11,8 @@
<CrowStbSharp>true</CrowStbSharp>
<CrowDebugLogEnabled>false</CrowDebugLogEnabled>
<CrowDebugStatsEnabled>true</CrowDebugStatsEnabled>
- <CrowDesignModeEnabled>true</CrowDesignModeEnabled>
-
- <GlfwSharpVersion>0.2.11-beta</GlfwSharpVersion>
+ <CrowDesignModeEnabled>false</CrowDesignModeEnabled>
+ <CrowVkvgBackend>true</CrowVkvgBackend>
+ <GlfwSharpVersion>0.2.12-beta</GlfwSharpVersion>
</PropertyGroup>
</Project>
diff --git a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs
index b369d248..3e11aa3f 100644
--- a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs
+++ b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs
@@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
-using Crow.Cairo;
+using Crow.Drawing;
using Crow.DebugLogger;
using DebugLogAnalyzer;
diff --git a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs
index 2ac0326f..086e7152 100644
--- a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs
+++ b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs
@@ -10,7 +10,7 @@ using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
-using Crow.Cairo;
+using Crow.Drawing;
using Crow.DebugLogger;
using DebugLogAnalyzer;
diff --git a/Samples/DebugLogAnalyzer/src/DebugInterface.cs b/Samples/DebugLogAnalyzer/src/DebugInterface.cs
index a15b63aa..d37b0752 100644
--- a/Samples/DebugLogAnalyzer/src/DebugInterface.cs
+++ b/Samples/DebugLogAnalyzer/src/DebugInterface.cs
@@ -3,7 +3,7 @@
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-using Crow.Cairo;
+using Crow.Drawing;
using System.Threading;
using Samples;
diff --git a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs
index c74bae64..70c4f9b1 100644
--- a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs
+++ b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs
@@ -7,7 +7,7 @@ using Glfw;
using System.Reflection;
using System.Runtime.Loader;
using System.IO;
-using Crow.Cairo;
+using Crow.Drawing;
using System.Diagnostics;
using System.Collections.Generic;
using Crow.DebugLogger;
diff --git a/Samples/common/src/Editor.cs b/Samples/common/src/Editor.cs
index 686afaed..22418f31 100644
--- a/Samples/common/src/Editor.cs
+++ b/Samples/common/src/Editor.cs
@@ -6,7 +6,7 @@ using System;
using Glfw;
using Crow.Text;
using System.Collections.Generic;
-using Crow.Cairo;
+using Crow.Drawing;
using System.Threading.Tasks;
using System.Linq;
using System.Diagnostics.CodeAnalysis;
diff --git a/Samples/common/src/SampleBase.cs b/Samples/common/src/SampleBase.cs
index 8d7718ed..9784304a 100644
--- a/Samples/common/src/SampleBase.cs
+++ b/Samples/common/src/SampleBase.cs
@@ -10,6 +10,8 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
+using Crow.Drawing;
+
namespace Samples
{
public class SampleBase : Interface
@@ -376,7 +378,7 @@ namespace Samples
initCommands();
base.OnInitialized();
}
- protected override void processDrawing(Crow.Cairo.Context ctx)
+ protected override void processDrawing(Context ctx)
{
base.processDrawing(ctx);
}
diff --git a/Samples/common/ui/Interfaces/TemplatedControl/testEnumSelector.crow b/Samples/common/ui/Interfaces/TemplatedControl/testEnumSelector.crow
index 63590efd..1e6e03fa 100644
--- a/Samples/common/ui/Interfaces/TemplatedControl/testEnumSelector.crow
+++ b/Samples/common/ui/Interfaces/TemplatedControl/testEnumSelector.crow
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<VerticalStack Spacing="5" Margin="5">
- <EnumSelector Caption="Vertical Alignemnt" EnumValue="{²CurrentVAlign}" Width="200">
+ <EnumSelector Caption="Vertical Alignemnt" EnumValue="{²CurrentVAlign}" Width="200" Background="Onyx">
<Template>
<Popper Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}">
<Template>