<ProjectReference Include="..\..\Drawing2D\Drawing2D.csproj" />
</ItemGroup>
+ <PropertyGroup Condition=" '$(CrowStbSharp)' == 'true'">
+ <DefineConstants>$(DefineConstants);STB_SHARP</DefineConstants>
+ </PropertyGroup>
</Project>
}
}
- public IntPtr Handle {
- get {
- return handle;
- }
- }
+ public IntPtr Handle => handle;
public Operator Operator {
- set {
- NativeMethods.cairo_set_operator (handle, value);
- }
-
- get {
- return NativeMethods.cairo_get_operator (handle);
- }
+ set => NativeMethods.cairo_set_operator (handle, value);
+ get => NativeMethods.cairo_get_operator (handle);
}
-
public double Tolerance {
- get {
- return NativeMethods.cairo_get_tolerance (handle);
- }
-
- set {
- NativeMethods.cairo_set_tolerance (handle, value);
- }
+ get => NativeMethods.cairo_get_tolerance (handle);
+ set => NativeMethods.cairo_set_tolerance (handle, value);
}
-
public FillRule FillRule {
- set {
- NativeMethods.cairo_set_fill_rule (handle, value);
- }
-
- get {
- return NativeMethods.cairo_get_fill_rule (handle);
- }
+ set => NativeMethods.cairo_set_fill_rule (handle, value);
+ get => NativeMethods.cairo_get_fill_rule (handle);
}
-
public double LineWidth {
- set {
- NativeMethods.cairo_set_line_width (handle, value);
- }
-
- get {
- return NativeMethods.cairo_get_line_width (handle);
- }
+ set => NativeMethods.cairo_set_line_width (handle, value);
+ get => NativeMethods.cairo_get_line_width (handle);
}
-
public LineCap LineCap {
set {
NativeMethods.cairo_set_line_cap (handle, value);
public void SetSource (Pattern source)
{
- NativeMethods.cairo_set_source (handle, source.Handle);
+ NativeMethods.cairo_set_source (handle, source.handle);
}
public Pattern GetSource ()
return NativeMethods.cairo_has_current_point (handle);
}
}
-
- [Obsolete ("Use GetTarget/SetTarget")]
- public Surface Target {
- set {
- if (handle != IntPtr.Zero)
- NativeMethods.cairo_destroy (handle);
-
- handle = NativeMethods.cairo_create (value.Handle);
- }
-
- get {
- return GetTarget ();
- }
- }
-
- public Surface GetTarget ()
- {
- return Surface.Lookup (NativeMethods.cairo_get_target (handle), false);
- }
-
+ public Surface GetTarget () => Surface.Lookup (NativeMethods.cairo_get_target (handle), false);
public void SetTarget (Surface target)
{
if (handle != IntPtr.Zero)
NativeMethods.cairo_destroy (handle);
handle = NativeMethods.cairo_create (target.Handle);
}
-
- [Obsolete("Use GetScaledFont/SetScaledFont")]
- public ScaledFont ScaledFont {
- set {
- SetScaledFont (value);
- }
-
- get {
- return GetScaledFont ();
- }
- }
-
public ScaledFont GetScaledFont ()
- {
- return new ScaledFont (NativeMethods.cairo_get_scaled_font (handle), false);
- }
-
+ => new ScaledFont (NativeMethods.cairo_get_scaled_font (handle), false);
public void SetScaledFont (ScaledFont font)
- {
- NativeMethods.cairo_set_scaled_font (handle, font.Handle);
- }
-
- public uint ReferenceCount {
- get { return NativeMethods.cairo_get_reference_count (handle); }
- }
-
+ => NativeMethods.cairo_set_scaled_font (handle, font.Handle);
+ public uint ReferenceCount => NativeMethods.cairo_get_reference_count (handle);
public void SetSource (Color color)
- {
- NativeMethods.cairo_set_source_rgba (handle, color.R / 255.0, color.G / 255.0, color.B / 255.0, color.A / 255.0);
- }
-
+ => NativeMethods.cairo_set_source_rgba (handle, color.R / 255.0, color.G / 255.0, color.B / 255.0, color.A / 255.0);
public void SetSource (double r, double g, double b)
{
NativeMethods.cairo_set_source_rgb (handle, r, g, b);
NativeMethods.cairo_set_source_surface (handle, source.Handle, 0, 0);
}
-#region Path methods
-
- public void NewPath ()
- {
- NativeMethods.cairo_new_path (handle);
- }
-
- public void NewSubPath ()
- {
- NativeMethods.cairo_new_sub_path (handle);
- }
-
- public void MoveTo (PointD p)
- {
- MoveTo (p.X, p.Y);
- }
-
- public void MoveTo (double x, double y)
- {
- NativeMethods.cairo_move_to (handle, x, y);
- }
-
- public void LineTo (PointD p)
- {
- LineTo (p.X, p.Y);
- }
-
- public void LineTo (double x, double y)
- {
- NativeMethods.cairo_line_to (handle, x, y);
- }
-
- public void CurveTo (PointD p1, PointD p2, PointD p3)
- {
- CurveTo (p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y);
- }
-
+ #region Path methods
+ public void NewPath () => NativeMethods.cairo_new_path (handle);
+ public void NewSubPath () => NativeMethods.cairo_new_sub_path (handle);
+ public void MoveTo (PointD p) => MoveTo (p.X, p.Y);
+ public void MoveTo (double x, double y) => NativeMethods.cairo_move_to (handle, x, y);
+ public void LineTo (PointD p) => LineTo (p.X, p.Y);
+ public void LineTo (double x, double y) => NativeMethods.cairo_line_to (handle, x, y);
+ public void CurveTo (PointD p1, PointD p2, PointD p3) => CurveTo (p1.X, p1.Y, p2.X, p2.Y, p3.X, p3.Y);
public void CurveTo (double x1, double y1, double x2, double y2, double x3, double y3)
- {
- NativeMethods.cairo_curve_to (handle, x1, y1, x2, y2, x3, y3);
- }
-
- public void RelMoveTo (Distance d)
- {
- RelMoveTo (d.Dx, d.Dy);
- }
-
- public void RelMoveTo (double dx, double dy)
- {
- NativeMethods.cairo_rel_move_to (handle, dx, dy);
- }
-
- public void RelLineTo (Distance d)
- {
- RelLineTo (d.Dx, d.Dy);
- }
-
- public void RelLineTo (double dx, double dy)
- {
- NativeMethods.cairo_rel_line_to (handle, dx, dy);
- }
-
+ => NativeMethods.cairo_curve_to (handle, x1, y1, x2, y2, x3, y3);
+ public void RelMoveTo (Distance d) => RelMoveTo (d.Dx, d.Dy);
+ public void RelMoveTo (double dx, double dy) => NativeMethods.cairo_rel_move_to (handle, dx, dy);
+ public void RelLineTo (Distance d) => RelLineTo (d.Dx, d.Dy);
+ public void RelLineTo (double dx, double dy) => NativeMethods.cairo_rel_line_to (handle, dx, dy);
public void RelCurveTo (Distance d1, Distance d2, Distance d3)
- {
- RelCurveTo (d1.Dx, d1.Dy, d2.Dx, d2.Dy, d3.Dx, d3.Dy);
- }
-
+ => RelCurveTo (d1.Dx, d1.Dy, d2.Dx, d2.Dy, d3.Dx, d3.Dy);
public void RelCurveTo (double dx1, double dy1, double dx2, double dy2, double dx3, double dy3)
- {
- NativeMethods.cairo_rel_curve_to (handle, dx1, dy1, dx2, dy2, dx3, dy3);
- }
-
+ => NativeMethods.cairo_rel_curve_to (handle, dx1, dy1, dx2, dy2, dx3, dy3);
public void Arc (double xc, double yc, double radius, double angle1, double angle2)
- {
- NativeMethods.cairo_arc (handle, xc, yc, radius, angle1, angle2);
- }
+ => NativeMethods.cairo_arc (handle, xc, yc, radius, angle1, angle2);
public void Arc (PointD center, double radius, double angle1, double angle2)
- {
- NativeMethods.cairo_arc (handle, center.X, center.Y, radius, angle1, angle2);
- }
-
+ => NativeMethods.cairo_arc (handle, center.X, center.Y, radius, angle1, angle2);
public void ArcNegative (double xc, double yc, double radius, double angle1, double angle2)
- {
- NativeMethods.cairo_arc_negative (handle, xc, yc, radius, angle1, angle2);
- }
+ => NativeMethods.cairo_arc_negative (handle, xc, yc, radius, angle1, angle2);
public void ArcNegative (PointD center, double radius, double angle1, double angle2)
- {
- NativeMethods.cairo_arc_negative (handle, center.X, center.Y, radius, angle1, angle2);
- }
-
+ => NativeMethods.cairo_arc_negative (handle, center.X, center.Y, radius, angle1, angle2);
public void Rectangle (Rectangle rectangle)
- {
- Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
+ => Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
public void Rectangle (RectangleD rectangle)
- {
- Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
- }
-
+ => Rectangle (rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
public void Rectangle (PointD p, double width, double height)
- {
- Rectangle (p.X, p.Y, width, height);
- }
-
+ => Rectangle (p.X, p.Y, width, height);
public void Rectangle (double x, double y, double width, double height)
- {
- NativeMethods.cairo_rectangle (handle, x, y, width, height);
- }
-
- public void ClosePath ()
- {
- NativeMethods.cairo_close_path (handle);
- }
-
- public Path CopyPath ()
- {
- return new Path (NativeMethods.cairo_copy_path (handle));
- }
-
- public Path CopyPathFlat ()
- {
- return new Path (NativeMethods.cairo_copy_path_flat (handle));
- }
-
- public void AppendPath (Path path)
- {
- NativeMethods.cairo_append_path (handle, path.Handle);
- }
-
-#endregion
-
-#region Painting Methods
- public void Paint ()
- {
- NativeMethods.cairo_paint (handle);
- }
-
- public void PaintWithAlpha (double alpha)
- {
- NativeMethods.cairo_paint_with_alpha (handle, alpha);
- }
-
- public void Mask (Pattern pattern)
- {
- NativeMethods.cairo_mask (handle, pattern.Handle);
- }
-
+ => NativeMethods.cairo_rectangle (handle, x, y, width, height);
+ public void ClosePath () => NativeMethods.cairo_close_path (handle);
+ public Path CopyPath () => new Path (NativeMethods.cairo_copy_path (handle));
+ public Path CopyPathFlat () => new Path (NativeMethods.cairo_copy_path_flat (handle));
+ public void AppendPath (Path path) => NativeMethods.cairo_append_path (handle, path.Handle);
+ #endregion
+
+ #region Painting Methods
+ public void Paint () => NativeMethods.cairo_paint (handle);
+ public void PaintWithAlpha (double alpha) => NativeMethods.cairo_paint_with_alpha (handle, alpha);
+ public void Mask (Pattern pattern) => NativeMethods.cairo_mask (handle, pattern.handle);
public void MaskSurface (Surface surface, double surface_x, double surface_y)
- {
- NativeMethods.cairo_mask_surface (handle, surface.Handle, surface_x, surface_y);
- }
-
- public void Stroke ()
- {
- NativeMethods.cairo_stroke (handle);
- }
-
- public void StrokePreserve ()
- {
- NativeMethods.cairo_stroke_preserve (handle);
- }
-
+ => NativeMethods.cairo_mask_surface (handle, surface.Handle, surface_x, surface_y);
+ public void Stroke () => NativeMethods.cairo_stroke (handle);
+ public void StrokePreserve () => NativeMethods.cairo_stroke_preserve (handle);
public Rectangle StrokeExtents ()
{
double x1, y1, x2, y2;
return new Rectangle ((int)x1, (int)y1, (int)(x2 - x1), (int)(y2 - y1));
}
- public void Fill ()
- {
- NativeMethods.cairo_fill (handle);
- }
-
+ public void Fill () => NativeMethods.cairo_fill (handle);
+ public void FillPreserve () => NativeMethods.cairo_fill_preserve (handle);
public Rectangle FillExtents ()
{
double x1, y1, x2, y2;
return new Rectangle ((int)x1, (int)y1, (int)(x2 - x1), (int)(y2 - y1));
}
- public void FillPreserve ()
- {
- NativeMethods.cairo_fill_preserve (handle);
- }
-
-#endregion
-
- public void Clip ()
- {
- NativeMethods.cairo_clip (handle);
- }
-
- public void ClipPreserve ()
- {
- NativeMethods.cairo_clip_preserve (handle);
- }
-
- public void ResetClip ()
- {
- NativeMethods.cairo_reset_clip (handle);
- }
+ #endregion
- public bool InClip (double x, double y)
- {
- return NativeMethods.cairo_in_clip (handle, x, y);
- }
- public RectangleList GetClipRectangles (){
+ public void Clip () => NativeMethods.cairo_clip (handle);
+ public void ClipPreserve () => NativeMethods.cairo_clip_preserve (handle);
+ public void ResetClip () => NativeMethods.cairo_reset_clip (handle);
+ public bool InClip (double x, double y) => NativeMethods.cairo_in_clip (handle, x, y);
+ /*public RectangleList GetClipRectangles (){
return (RectangleList)Marshal.PtrToStructure (NativeMethods.cairo_copy_clip_rectangle_list (handle), typeof(RectangleList));
- }
+ }*/
public void ClipExtendRectangle (){
double x1, y1, x2, y2;
NativeMethods.cairo_clip_extents (handle, out x1, out y1, out x2, out y2);
- NativeMethods.cairo_rectangle (handle, x1, y1, x2 - x1, y2 - y1);
- }
- public bool InStroke (double x, double y)
- {
- return NativeMethods.cairo_in_stroke (handle, x, y);
- }
-
- public bool InFill (double x, double y)
- {
- return NativeMethods.cairo_in_fill (handle, x, y);
- }
-
- public Pattern PopGroup ()
- {
- return Pattern.Lookup (NativeMethods.cairo_pop_group (handle), true);
- }
-
- public void PopGroupToSource ()
- {
- NativeMethods.cairo_pop_group_to_source (handle);
- }
-
- public void PushGroup ()
- {
- NativeMethods.cairo_push_group (handle);
- }
-
- public void PushGroup (Content content)
- {
- NativeMethods.cairo_push_group_with_content (handle, content);
- }
-
- [Obsolete ("Use GetGroupTarget()")]
- public Surface GroupTarget {
- get {
- return GetGroupTarget ();
- }
- }
-
+ NativeMethods.cairo_rectangle (handle, x1, y1, x2 - x1, y2 - y1);
+ }
+ public bool InStroke (double x, double y) => NativeMethods.cairo_in_stroke (handle, x, y);
+ public bool InFill (double x, double y) => NativeMethods.cairo_in_fill (handle, x, y);
+ public Pattern PopGroup () => Pattern.Lookup (NativeMethods.cairo_pop_group (handle), true);
+ public void PopGroupToSource () => NativeMethods.cairo_pop_group_to_source (handle);
+ public void PushGroup () => NativeMethods.cairo_push_group (handle);
+ public void PushGroup (Content content) => NativeMethods.cairo_push_group_with_content (handle, content);
public Surface GetGroupTarget ()
{
IntPtr surface = NativeMethods.cairo_get_group_target (handle);
return Surface.Lookup (surface, false);
}
- public void Rotate (double angle)
- {
- NativeMethods.cairo_rotate (handle, angle);
- }
-
- public void Scale (double sx, double sy)
- {
- NativeMethods.cairo_scale (handle, sx, sy);
- }
-
- public void Translate (double tx, double ty)
- {
- NativeMethods.cairo_translate (handle, tx, ty);
- }
-
- public void Transform (Matrix m)
- {
- NativeMethods.cairo_transform (handle, m);
- }
+ public void Rotate (double angle) => NativeMethods.cairo_rotate (handle, angle);
+ public void Scale (double sx, double sy) => NativeMethods.cairo_scale (handle, sx, sy);
+ public void Translate (double tx, double ty) => NativeMethods.cairo_translate (handle, tx, ty);
+ public void Transform (Matrix m) => NativeMethods.cairo_transform (handle, m);
[Obsolete("Use UserToDevice instead")]
public void TransformPoint (ref double x, ref double y)
NativeMethods.cairo_device_to_user_distance (handle, ref dx, ref dy);
}
- public Matrix Matrix {
- set {
- NativeMethods.cairo_set_matrix (handle, value);
- }
-
- get {
- Matrix m = new Matrix();
- NativeMethods.cairo_get_matrix (handle, m);
- return m;
- }
- }
-
public void SetFontSize (double scale)
{
NativeMethods.cairo_set_font_size (handle, scale);
}
- public void IdentityMatrix ()
- {
- NativeMethods.cairo_identity_matrix (handle);
- }
-
+ public void IdentityMatrix () => NativeMethods.cairo_identity_matrix (handle);
public Matrix FontMatrix {
get {
Matrix m;
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 = Text.Encoding.ToUtf8 (s, bytes, tabSize);
+ int encodedBytes = s.ToUtf8 (bytes, tabSize);
bytes[encodedBytes] = 0;
ShowText (bytes.Slice (0, encodedBytes + 1));
}
public TextExtents TextExtents (ReadOnlySpan<char> s, int tabSize) {
- TextExtents (s, tabSize, out TextExtents extents);
+ 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 = Text.Encoding.ToUtf8 (s, bytes, tabSize);
+ int encodedBytes = s.ToUtf8 (bytes, tabSize);
bytes[encodedBytes] = 0;
TextExtents (bytes.Slice (0, encodedBytes + 1), out extents);
}
return extents;
}
+
+ public void Flush()
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Clear()
+ {
+ throw new NotImplementedException();
+ }
+ public void MoveTo(Point p)
+ {
+ throw new NotImplementedException();
+ }
+ public void LineTo(Point p)
+ {
+ throw new NotImplementedException();
+ }
+
+/* public void Arc(float xc, float yc, float radius, float a1, float a2)
+ {
+ throw new NotImplementedException();
+ }
+ public void ArcNegative(float xc, float yc, float radius, float a1, float a2)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void MoveTo(float x, float y)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RelMoveTo(float x, float y)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void LineTo(float x, float y)
+ {
+ throw new NotImplementedException();
+ }
+ public void RelLineTo(float x, float y)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void RelCurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Scale(float sx, float sy)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void Translate(float dx, float dy)
+ {
+ throw new NotImplementedException();
+ }
+ public void Rotate(float alpha)
+ {
+ throw new NotImplementedException();
+ }
+ public void SetSource(float r, float g, float b, float a = 1)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetSource(ISurface surf, float x = 0, float y = 0)
+ {
+ throw new NotImplementedException();
+ }
+
+ public void SetSourceSurface(ISurface surf, float x = 0, float y = 0)
+ {
+ throw new NotImplementedException();
+ }
+*/
+ public void Translate(PointD p)
+ {
+ throw new NotImplementedException();
+ }
+ public void RenderSvg(IntPtr svgNativeHandle, string subId = null)
+ {
+ throw new NotImplementedException();
+ }
+ Matrix savedMat;
+ public void SaveTransformations()
+ => NativeMethods.cairo_get_matrix (handle, out savedMat);
+ public void RestoreTransformations()
+ => NativeMethods.cairo_set_matrix (handle, ref savedMat);
+ public void SetSource(IPattern pat) => NativeMethods.cairo_set_source (handle, pat.Handle);
+ public void SetSource(ISurface surf, double x = 0, double y = 0)
+ => NativeMethods.cairo_set_source_surface (handle, surf.Handle, x, y);
}
}
namespace Crow.CairoBackend
{
- public class DRMDevice : Device
+ public class DRMDevice : CairoDevice
{
public DRMDevice () : base (NativeMethods.cairo_drm_device_default (), true)
{
}
public int FileDescriptor {
- get { return NativeMethods.cairo_drm_device_get_fd (Handle); }
+ get { return NativeMethods.cairo_drm_device_get_fd (handle); }
}
- public void DeviceThrottle () { NativeMethods.cairo_drm_device_throttle (Handle);}
+ public void DeviceThrottle () { NativeMethods.cairo_drm_device_throttle (handle);}
}
}
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
+using System.IO;
+using System.Runtime.InteropServices;
using Drawing2D;
using Glfw;
namespace Crow.CairoBackend
{
- public class Device : IDevice
- {
- IntPtr handle = IntPtr.Zero;
- /// <summary> Global font rendering settings for Cairo </summary>
- FontOptions FontRenderingOptions;
- /// <summary> Global font rendering settings for Cairo </summary>
- Antialias Antialias = Antialias.Subpixel;
-
- protected Device()
- {
- FontRenderingOptions = new FontOptions ();
- FontRenderingOptions.Antialias = Antialias.Subpixel;
- FontRenderingOptions.HintMetrics = HintMetrics.On;
- FontRenderingOptions.HintStyle = HintStyle.Full;
- FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default;
- }
-
- protected Device (IntPtr ptr) : this (ptr, true)
- {
- }
-
- protected Device (IntPtr handle, bool owner)
+ public abstract class CairoDevice : Device {
+ protected IntPtr handle = IntPtr.Zero;
+ public IntPtr Handle => handle;
+ protected CairoDevice (IntPtr handle, bool owner = true)
{
this.handle = handle;
if (!owner)
if (CairoDebug.Enabled)
CairoDebug.OnAllocated (handle);
}
-
- ~Device ()
- {
- Dispose (false);
- }
-
- public IntPtr Handle {
- get {
- return handle;
- }
- }
public string Status {
get {
return System.Runtime.InteropServices.Marshal.PtrToStringAuto(NativeMethods.cairo_status_to_string (NativeMethods.cairo_device_status (handle)));
}
}
- public void SetThreadAware (bool value){
- NativeMethods.cairo_gl_device_set_thread_aware (handle, value ? 1 : 0);
- }
public Status Acquire()
{
return NativeMethods.cairo_device_acquire (handle);
NativeMethods.cairo_device_release (handle);
}
- public void Dispose ()
+ protected override void Dispose (bool disposing)
{
- Dispose (true);
- GC.SuppressFinalize (this);
- }
+ base.Dispose (disposing);
- protected virtual void Dispose (bool disposing)
- {
if (!disposing || CairoDebug.Enabled)
CairoDebug.OnDisposed<Device> (handle, disposing);
NativeMethods.cairo_device_destroy (handle);
- FontRenderingOptions.Dispose ();
handle = IntPtr.Zero;
}
+ }
+ public class Device : IDevice
+ {
+ /// <summary> Global font rendering settings for Cairo </summary>
+ FontOptions FontRenderingOptions;
+ /// <summary> Global font rendering settings for Cairo </summary>
+ Antialias Antialias = Antialias.Subpixel;
- public void GetDpy(out int hdpy, out int vdpy)
+ public Device()
{
- throw new NotImplementedException();
+ FontRenderingOptions = new FontOptions ();
+ FontRenderingOptions.Antialias = Antialias.Subpixel;
+ FontRenderingOptions.HintMetrics = HintMetrics.On;
+ FontRenderingOptions.HintStyle = HintStyle.Full;
+ FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default;
}
- public void SetDpy(int hdpy, int vdpy)
+ ~Device ()
+ {
+ Dispose (false);
+ }
+
+ #region IDevice implementation
+ public void GetDpy(out int hdpy, out int vdpy)
{
throw new NotImplementedException();
}
- public virtual ISurface CreateSurface(int width, int height)
+ public void SetDpy(int hdpy, int vdpy)
{
throw new NotImplementedException();
}
+ public IRegion CreateRegion () => new Region ();
+ public virtual ISurface CreateSurface(int width, int height)
+ => new ImageSurface (Format.ARGB32, width, height);
+ public virtual ISurface CreateSurface(byte[] data, int width, int height)
+ => new ImageSurface (data, Format.ARGB32, width, height, 4 * width);
+
public ISurface CreateSurface (IntPtr nativeWindoPointer, int width, int height) {
switch (Environment.OSVersion.Platform) {
case PlatformID.Unix:
Context gr = new Context (surf);
gr.FontOptions = FontRenderingOptions;
gr.Antialias = Antialias;
- throw new NotImplementedException();
+ return gr;
+ }
+ public byte[] LoadBitmap (Stream stream, out Size dimensions) {
+ byte[] image;
+#if STB_SHARP
+ StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
+ image = new byte[stbi.Data.Length];
+ //rgba to argb for cairo.
+ for (int i = 0; i < stbi.Data.Length; i += 4) {
+ image[i] = stbi.Data[i + 2];
+ image[i + 1] = stbi.Data[i + 1];
+ image[i + 2] = stbi.Data[i];
+ image[i + 3] = stbi.Data[i + 3];
+ }
+ dimensions = new Size (stbi.Width, stbi.Height);
+#else
+ using (StbImage stbi = new StbImage (stream)) {
+ image = new byte [stbi.Size];
+ for (int i = 0; i < stbi.Size; i+=4) {
+ //rgba to argb for cairo. ???? looks like bgra to me.
+ image [i] = Marshal.ReadByte (stbi.Handle, i + 2);
+ image [i + 1] = Marshal.ReadByte (stbi.Handle, i + 1);
+ image [i + 2] = Marshal.ReadByte (stbi.Handle, i);
+ image [i + 3] = Marshal.ReadByte (stbi.Handle, i + 3);
+ }
+ dimensions = new Size (stbi.Width, stbi.Height);
+ }
+#endif
+ return image;
+ }
+ public ISvgHandle LoadSvg(Stream stream)
+ {
+ using (BinaryReader sr = new BinaryReader (stream))
+ return new SvgHandle (sr.ReadBytes ((int)stream.Length));
+ }
+
+ public ISvgHandle LoadSvg(string svgFragment) =>
+ new SvgHandle (System.Text.Encoding.Unicode.GetBytes (svgFragment));
+
+ public IGradient CreateGradient (GradientType gradientType, Rectangle bounds) {
+ switch (gradientType) {
+ case GradientType.Vertical:
+ return new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);
+ case GradientType.Horizontal:
+ return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Top);
+ case GradientType.Oblic:
+ return new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
+ case GradientType.Radial:
+ throw new NotImplementedException ();
+ }
+ return null;
+ }
+ #endregion
+
+ #region IDispose implementation
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (disposing)
+ FontRenderingOptions.Dispose ();
}
+ #endregion
}
}
namespace Crow.CairoBackend
{
- public class EGLDevice : Device
+ public class EGLDevice : GLDevice
{
public EGLDevice (IntPtr dpy, IntPtr gl_ctx) : base (NativeMethods.cairo_egl_device_create (dpy, gl_ctx), true)
{
--- /dev/null
+// 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;
+
+namespace Crow.CairoBackend
+{
+ public abstract class GLDevice : CairoDevice
+ {
+ protected GLDevice (IntPtr handle, bool owner = true) : base (handle, owner) {}
+ public void SetThreadAware (bool value) {
+ NativeMethods.cairo_gl_device_set_thread_aware (handle, value ? 1 : 0);
+ }
+
+ }
+}
+
public GLSurface (IntPtr ptr, bool own) : base (ptr, own)
{}
- public GLSurface (Device device, Content content, uint tex, int width, int height)
+ public GLSurface (CairoDevice device, Content content, uint tex, int width, int height)
: base (NativeMethods.cairo_gl_surface_create_for_texture (device.Handle, (uint)content, tex, width, height), true)
{}
namespace Crow.CairoBackend
{
- public class GLXDevice : Device
+ public class GLXDevice : CairoDevice
{
public GLXDevice (IntPtr dpy, IntPtr gl_ctx) : base (NativeMethods.cairo_glx_device_create (dpy, gl_ctx), true)
{
}
public IntPtr Display {
- get { return NativeMethods.cairo_glx_device_get_display (Handle); }
+ get { return NativeMethods.cairo_glx_device_get_display (handle); }
}
public IntPtr Context {
- get { return NativeMethods.cairo_glx_device_get_context (Handle); }
+ get { return NativeMethods.cairo_glx_device_get_context (handle); }
}
}
}
//
using System;
-using Color = Drawing2D.Color;
+using Drawing2D;
namespace Crow.CairoBackend {
- public class Gradient : Pattern
+ public class Gradient : Pattern, IGradient
{
protected Gradient (IntPtr handle, bool owned) : base (handle, owned)
{
public int ColorStopCount {
get {
int cnt;
- NativeMethods.cairo_pattern_get_color_stop_count (Handle, out cnt);
+ NativeMethods.cairo_pattern_get_color_stop_count (handle, out cnt);
return cnt;
}
}
-
- public Status AddColorStop (double offset, Color c)
- {
- NativeMethods.cairo_pattern_add_color_stop_rgba (Handle, offset, c.R / 255.0, c.G / 255.0, c.B / 255.0, c.A / 255.0);
- return Status;
- }
+ #region IGradient implementation
+ public void AddColorStop (double offset, Color c)
+ => NativeMethods.cairo_pattern_add_color_stop_rgba (handle, offset, c.R / 255.0, c.G / 255.0, c.B / 255.0, c.A / 255.0);
+ public void AddColorStop(float offset, float r, float g, float b, float a = 1)
+ => NativeMethods.cairo_pattern_add_color_stop_rgba (handle, offset, r, g, b, a);
+ #endregion
public Status AddColorStopRgb (double offset, Color c)
{
- NativeMethods.cairo_pattern_add_color_stop_rgb (Handle, offset, c.R / 255.0, c.G / 255.0 / 255.0, c.B / 255.0);
+ NativeMethods.cairo_pattern_add_color_stop_rgb (handle, offset, c.R / 255.0, c.G / 255.0 / 255.0, c.B / 255.0);
return Status;
}
}
double x0, y0, x1, y1;
PointD[] points = new PointD [2];
- NativeMethods.cairo_pattern_get_linear_points (Handle, out x0, out y0, out x1, out y1);
+ NativeMethods.cairo_pattern_get_linear_points (handle, out x0, out y0, out x1, out y1);
points[0] = new PointD (x0, y0);
points[1] = new PointD (x1, y1);
namespace Crow.CairoBackend {
[StructLayout(LayoutKind.Sequential)]
- public class Matrix //: ICloneable
+ public struct Matrix //: ICloneable
{
public double Xx;
public double Yx;
this.Xx = xx; this.Yx = yx; this.Xy = xy;
this.Yy = yy; this.X0 = x0; this.Y0 = y0;
}
-
- public Matrix ()
- {
- this.InitIdentity ();
- }
-
public bool IsIdentity ()
{
return (this == new Matrix ());
//no idea why this is here, the base one is identical, but we can't remove it now
public new Extend Extend {
- set { NativeMethods.cairo_pattern_set_extend (Handle, value); }
- get { return NativeMethods.cairo_pattern_get_extend (Handle); }
+ set { NativeMethods.cairo_pattern_set_extend (handle, value); }
+ get { return NativeMethods.cairo_pattern_get_extend (handle); }
}
public Filter Filter {
- set { NativeMethods.cairo_pattern_set_filter (Handle, value); }
- get { return NativeMethods.cairo_pattern_get_filter (Handle); }
+ set { NativeMethods.cairo_pattern_set_filter (handle, value); }
+ get { return NativeMethods.cairo_pattern_get_filter (handle); }
}
public void BeginPatch(){
- NativeMethods.cairo_mesh_pattern_begin_patch (Handle);
+ NativeMethods.cairo_mesh_pattern_begin_patch (handle);
}
public void EndPatch(){
- NativeMethods.cairo_mesh_pattern_end_patch (Handle);
+ NativeMethods.cairo_mesh_pattern_end_patch (handle);
}
public void MoveTo(double x, double y){
- NativeMethods.cairo_mesh_pattern_move_to (Handle, x, y);
+ NativeMethods.cairo_mesh_pattern_move_to (handle, x, y);
}
public void MoveTo (PointD p) {
- NativeMethods.cairo_mesh_pattern_move_to (Handle, p.X, p.Y);
+ NativeMethods.cairo_mesh_pattern_move_to (handle, p.X, p.Y);
}
public void LineTo(double x, double y){
- NativeMethods.cairo_mesh_pattern_line_to (Handle, x, y);
+ NativeMethods.cairo_mesh_pattern_line_to (handle, x, y);
}
public void LineTo (PointD p) {
- NativeMethods.cairo_mesh_pattern_line_to (Handle, p.X, p.Y);
+ NativeMethods.cairo_mesh_pattern_line_to (handle, p.X, p.Y);
}
public void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
- NativeMethods.cairo_mesh_pattern_curve_to (Handle, x1, y1, x2, y2, x3, y3);
+ NativeMethods.cairo_mesh_pattern_curve_to (handle, x1, y1, x2, y2, x3, y3);
}
public void SetControlPoint(uint point_num, double x, double y){
- NativeMethods.cairo_mesh_pattern_set_control_point (Handle, point_num, x, y);
+ NativeMethods.cairo_mesh_pattern_set_control_point (handle, point_num, x, y);
}
public void SetControlPoint (uint point_num, PointD p) {
- NativeMethods.cairo_mesh_pattern_set_control_point (Handle, point_num, p.X, p.Y);
+ NativeMethods.cairo_mesh_pattern_set_control_point (handle, point_num, p.X, p.Y);
}
public void SetCornerColorRGB(uint corner_num, double r, double g, double b){
- NativeMethods.cairo_mesh_pattern_set_corner_color_rgb (Handle, corner_num, r, g, b);
+ NativeMethods.cairo_mesh_pattern_set_corner_color_rgb (handle, corner_num, r, g, b);
}
public void SetCornerColorRGBA(uint corner_num, double r, double g, double b, double a){
- NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (Handle, corner_num, r, g, b, a);
+ NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (handle, corner_num, r, g, b, a);
}
public void SetCornerColor (uint corner_num, Color c) {
- NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (Handle, corner_num, c.R, c.G, c.B, c.A);
+ NativeMethods.cairo_mesh_pattern_set_corner_color_rgba (handle, corner_num, c.R, c.G, c.B, c.A);
}
public uint PatchCount {
get {
uint count = 0;
- NativeMethods.cairo_mesh_pattern_get_patch_count(Handle, out count);
+ NativeMethods.cairo_mesh_pattern_get_patch_count(handle, out count);
return count;
}
}
public Path GetPath(uint patch_num){
- return new Path(NativeMethods.cairo_mesh_pattern_get_path(Handle, patch_num));
+ return new Path(NativeMethods.cairo_mesh_pattern_get_path(handle, patch_num));
}
public PointD GetControlPoint(uint point_num, uint patch_num = 0) {
- NativeMethods.cairo_mesh_pattern_get_control_point (Handle, patch_num, point_num, out double x, out double y);
+ NativeMethods.cairo_mesh_pattern_get_control_point (handle, patch_num, point_num, out double x, out double y);
return new PointD (x, y);
}
public void GetCornerColorRGBA(){
internal static extern double cairo_get_line_width (IntPtr cr);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void cairo_get_matrix (IntPtr cr, Matrix matrix);
+ internal static extern void cairo_get_matrix (IntPtr cr, out Matrix matrix);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
internal static extern double cairo_get_miter_limit (IntPtr cr);
internal static extern void cairo_set_line_width (IntPtr cr, double width);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
- internal static extern void cairo_set_matrix (IntPtr cr, Matrix matrix);
+ internal static extern void cairo_set_matrix (IntPtr cr, ref Matrix matrix);
[DllImport (cairo, CallingConvention=CallingConvention.Cdecl)]
internal static extern void cairo_set_miter_limit (IntPtr cr, double limit);
// 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
//
using System;
-using System.Collections;
using Drawing2D;
-namespace Crow.CairoBackend {
-
- public class Pattern : IDisposable
+namespace Crow.CairoBackend
+{
+ public class Pattern : IPattern
{
- [Obsolete]
- protected IntPtr pattern = IntPtr.Zero;
-
+ internal IntPtr handle;
+ public IntPtr Handle => handle;
public static Pattern Lookup (IntPtr pattern, bool owner)
{
if (pattern == IntPtr.Zero)
return null;
-
+
PatternType pt = NativeMethods.cairo_pattern_get_type (pattern);
switch (pt) {
case PatternType.Solid:
}
}
- [Obsolete]
- protected Pattern ()
- {
- }
-
internal Pattern (IntPtr handle, bool owned)
{
- Handle = handle;
+ this.handle = handle;
if (!owned)
NativeMethods.cairo_pattern_reference (handle);
if (CairoDebug.Enabled)
CairoDebug.OnAllocated (handle);
}
- ~Pattern ()
- {
- Dispose (false);
- }
-
[Obsolete ("Use the SurfacePattern constructor")]
public Pattern (Surface surface)
: this ( NativeMethods.cairo_pattern_create_for_surface (surface.Handle), true)
{
}
-
+
[Obsolete]
protected void Reference ()
{
- NativeMethods.cairo_pattern_reference (pattern);
- }
-
- public void Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this);
- }
-
- protected virtual void Dispose (bool disposing)
- {
- if (!disposing || CairoDebug.Enabled)
- CairoDebug.OnDisposed<Pattern> (Handle, disposing);
-
- if (!disposing|| Handle == IntPtr.Zero)
- return;
-
- NativeMethods.cairo_pattern_destroy (Handle);
- Handle = IntPtr.Zero;
+ NativeMethods.cairo_pattern_reference (handle);
}
- [Obsolete ("Use Dispose()")]
- public void Destroy ()
- {
- Dispose ();
- }
- public Status Status
- {
- get { return NativeMethods.cairo_pattern_status (Handle); }
- }
- public Extend Extend
- {
- get { return NativeMethods.cairo_pattern_get_extend (Handle); }
- set { NativeMethods.cairo_pattern_set_extend (Handle, value); }
- }
+ public Status Status => NativeMethods.cairo_pattern_status (handle);
public Matrix Matrix {
- set {
- NativeMethods.cairo_pattern_set_matrix (Handle, value);
- }
-
+ set => NativeMethods.cairo_pattern_set_matrix (handle, value);
get {
Matrix m = new Matrix ();
- NativeMethods.cairo_pattern_get_matrix (Handle, m);
+ NativeMethods.cairo_pattern_get_matrix (handle, m);
return m;
}
}
-#pragma warning disable 612
- public IntPtr Handle {
- get { return pattern; }
- private set { pattern = value; }
+ public PatternType PatternType => NativeMethods.cairo_pattern_get_type (handle);
+
+ #region IPattern implementation
+ public Extend Extend
+ {
+ get { return NativeMethods.cairo_pattern_get_extend (handle); }
+ set { NativeMethods.cairo_pattern_set_extend (handle, value); }
+ }
+ public Filter Filter {
+ get => NativeMethods.cairo_pattern_get_filter (handle);
+ set => NativeMethods.cairo_pattern_set_filter (handle, value);
}
-#pragma warning restore 612
+ #endregion
- [Obsolete]
- public IntPtr Pointer {
- get { return pattern; }
+ ~Pattern ()
+ {
+ Dispose (false);
}
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Pattern> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
- public PatternType PatternType {
- get { return NativeMethods.cairo_pattern_get_type (Handle); }
+ NativeMethods.cairo_pattern_destroy (handle);
+ handle = IntPtr.Zero;
}
}
}
//
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Drawing2D;
namespace Crow.CairoBackend
{
[StructLayout(LayoutKind.Sequential)]
- public struct RectangleList {
+ struct RectangleList {
public Status Status;
public IntPtr Rectangles;
public int NumRectangles;
}
- public enum RegionOverlap {
- In,
- Out,
- Part,
- }
- public class Region : IDisposable {
+ public class Region : IRegion {
IntPtr handle;
- public IntPtr Handle {
- get { return handle; }
- }
-
- [Obsolete]
- public Region (IntPtr handle) : this (handle, false) {}
+ #region CTOR
public Region (IntPtr handle, bool owned)
{
this.handle = handle;
if (CairoDebug.Enabled)
CairoDebug.OnAllocated (handle);
}
-
public Region () : this (NativeMethods.cairo_region_create () , true)
- {
- }
-
- public Region (Rectangle rect)
- {
+ {}
+ public Region (Rectangle rect) {
handle = NativeMethods.cairo_region_create_rectangle (ref rect);
}
-
- public Region (RectangleList rects)
- {
- handle = NativeMethods.cairo_region_create_rectangles (rects.Rectangles, rects.NumRectangles);
- }
-
- public Region Copy ()
- {
- return new Region (NativeMethods.cairo_region_copy (Handle), true);
- }
-
- #region IDisposable
- ~Region ()
- {
- Dispose (false);
- }
-
- public void Dispose ()
- {
- Dispose (true);
- GC.SuppressFinalize (this);
- }
-
- protected virtual void Dispose (bool disposing)
- {
- if (!disposing || CairoDebug.Enabled)
- CairoDebug.OnDisposed<Region> (handle, disposing);
-
- if (!disposing|| handle == IntPtr.Zero)
- return;
-
- NativeMethods.cairo_region_destroy (Handle);
- handle = IntPtr.Zero;
- }
#endregion
- public override bool Equals (object obj)
- {
- return (obj is Region) && NativeMethods.cairo_region_equal (Handle, (obj as Region).Handle);
- }
+ public Region Copy () => new Region (NativeMethods.cairo_region_copy (handle), true);
- public override int GetHashCode ()
- {
- return Handle.GetHashCode ();
- }
public Status Status {
- get { return NativeMethods.cairo_region_status (Handle); }
+ get { return NativeMethods.cairo_region_status (handle); }
}
public Rectangle Extents {
get {
Rectangle result;
- NativeMethods.cairo_region_get_extents (Handle, out result);
+ NativeMethods.cairo_region_get_extents (handle, out result);
return result;
}
}
- public int NumRectangles {
- get { return NativeMethods.cairo_region_num_rectangles (Handle); }
- }
-
- public Rectangle GetRectangle (int nth)
- {
- Rectangle val;
- NativeMethods.cairo_region_get_rectangle (Handle, nth, out val);
- return val;
- }
-
- public bool IsEmpty {
- get { return NativeMethods.cairo_region_is_empty (Handle); }
- }
-
- public RegionOverlap Contains (Rectangle rectangle)
- {
- return NativeMethods.cairo_region_contains_rectangle (Handle, ref rectangle);
- }
-
public bool Contains (int x, int y)
{
- return NativeMethods.cairo_region_contains_point (Handle, x, y);
+ return NativeMethods.cairo_region_contains_point (handle, x, y);
}
public void Translate (int dx, int dy)
{
- NativeMethods.cairo_region_translate (Handle, dx, dy);
+ NativeMethods.cairo_region_translate (handle, dx, dy);
}
public Status Subtract (Region other)
{
- return NativeMethods.cairo_region_subtract (Handle, other.Handle);
+ return NativeMethods.cairo_region_subtract (handle, other.handle);
}
public Status SubtractRectangle (Rectangle rectangle)
{
- return NativeMethods.cairo_region_subtract_rectangle (Handle, ref rectangle);
+ return NativeMethods.cairo_region_subtract_rectangle (handle, ref rectangle);
}
public Status Intersect (Region other)
{
- return NativeMethods.cairo_region_intersect (Handle, other.Handle);
+ return NativeMethods.cairo_region_intersect (handle, other.handle);
}
public Status IntersectRectangle (Rectangle rectangle)
{
- return NativeMethods.cairo_region_intersect_rectangle (Handle, ref rectangle);
+ return NativeMethods.cairo_region_intersect_rectangle (handle, ref rectangle);
}
public Status Union (Region other)
{
- return NativeMethods.cairo_region_union (Handle, other.Handle);
+ return NativeMethods.cairo_region_union (handle, other.handle);
}
- public Status UnionRectangle (Rectangle rectangle)
- {
- return NativeMethods.cairo_region_union_rectangle (Handle, ref rectangle);
- }
public Status Xor (Region other)
{
- return NativeMethods.cairo_region_xor (Handle, other.Handle);
+ return NativeMethods.cairo_region_xor (handle, other.handle);
}
public Status XorRectangle (Rectangle rectangle)
{
- return NativeMethods.cairo_region_xor_rectangle (Handle, ref rectangle);
+ return NativeMethods.cairo_region_xor_rectangle (handle, ref rectangle);
+ }
+
+ #region IRegion implementation
+ public bool IsEmpty => NativeMethods.cairo_region_is_empty (handle);
+ public int NumRectangles => NativeMethods.cairo_region_num_rectangles (handle);
+ public Rectangle GetRectangle (int nth)
+ {
+ Rectangle val;
+ NativeMethods.cairo_region_get_rectangle (handle, nth, out val);
+ return val;
}
+ public void UnionRectangle (Rectangle rectangle)
+ => NativeMethods.cairo_region_union_rectangle (handle, ref rectangle);
+ public bool OverlapOut (Rectangle rectangle) => Contains (rectangle) == RegionOverlap.Out;
+ public RegionOverlap Contains (Rectangle rectangle)
+ => NativeMethods.cairo_region_contains_rectangle (handle, ref rectangle);
public void Reset () {
if (IsEmpty)
return;
- NativeMethods.cairo_region_destroy (Handle);
+ NativeMethods.cairo_region_destroy (handle);
handle = NativeMethods.cairo_region_create ();
}
- public bool OverlapOut (Rectangle rectangle) => Contains (rectangle) == RegionOverlap.Out;
+
+ public bool Equals(IRegion other)
+ => other is Region r ? NativeMethods.cairo_region_equal (handle, r.handle) : false;
+ #endregion
+
+ public override bool Equals (object obj)
+ => obj is Region r ? NativeMethods.cairo_region_equal (handle, r.handle) : false;
+
+ public override int GetHashCode () => handle.GetHashCode ();
+
+ #region IDisposable
+ ~Region ()
+ {
+ Dispose (false);
+ }
+
+ public void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ if (!disposing || CairoDebug.Enabled)
+ CairoDebug.OnDisposed<Region> (handle, disposing);
+
+ if (!disposing|| handle == IntPtr.Zero)
+ return;
+
+ NativeMethods.cairo_region_destroy (handle);
+ handle = IntPtr.Zero;
+ }
+ #endregion
}
}
//
using System;
-using Color = Drawing2D.Color;
+using Drawing2D;
+
namespace Crow.CairoBackend {
public class SolidPattern : Pattern
public Color Color {
get {
double red, green, blue, alpha;
- NativeMethods.cairo_pattern_get_rgba (Handle, out red, out green, out blue, out alpha);
+ NativeMethods.cairo_pattern_get_rgba (handle, out red, out green, out blue, out alpha);
return new Color (red, green, blue, alpha);
}
}
//
using System;
-using System.Collections;
using Drawing2D;
namespace Crow.CairoBackend {
public class Surface : ISurface
{
- IntPtr handle = IntPtr.Zero;
+ protected IntPtr handle = IntPtr.Zero;
[Obsolete]
protected Surface()
NativeMethods.cairo_surface_destroy (handle);
handle = IntPtr.Zero;
}
- public virtual void SetSize (int width, int height) {
+ public virtual void Resize (int width, int height) {
}
public Status Finish ()
//no idea why this is here, the base one is identical, but we can't remove it now
public new Extend Extend {
- set { NativeMethods.cairo_pattern_set_extend (Handle, value); }
- get { return NativeMethods.cairo_pattern_get_extend (Handle); }
+ set { NativeMethods.cairo_pattern_set_extend (handle, value); }
+ get { return NativeMethods.cairo_pattern_get_extend (handle); }
}
public Filter Filter {
- set { NativeMethods.cairo_pattern_set_filter (Handle, value); }
- get { return NativeMethods.cairo_pattern_get_filter (Handle); }
+ set { NativeMethods.cairo_pattern_set_filter (handle, value); }
+ get { return NativeMethods.cairo_pattern_get_filter (handle); }
}
}
}
namespace Crow.CairoBackend
{
- public class WGLDevice : Device
+ public class WGLDevice : GLDevice
{
public WGLDevice (IntPtr hglrc) : base (NativeMethods.cairo_wgl_device_create (hglrc), true)
{
}
public IntPtr Context {
- get { return NativeMethods.cairo_wgl_device_get_context (Handle); }
+ get { return NativeMethods.cairo_wgl_device_get_context (handle); }
}
}
}
public class Win32Surface : Surface
{
+ IntPtr hdc;
internal Win32Surface (IntPtr handle, bool owns) : base (handle, owns)
{
}
public Win32Surface (IntPtr hdc)
: base (NativeMethods.cairo_win32_surface_create (hdc), true)
{
+ this.hdc = hdc;
+ }
+ public override void Resize(int width, int height)
+ {
+ if (hdc == IntPtr.Zero)
+ base.Resize (width, height);
+ else {
+ NativeMethods.cairo_surface_destroy (handle);
+ handle = NativeMethods.cairo_win32_surface_create (hdc);
+ }
}
}
}
IntPtr ptr = NativeMethods.cairo_xcb_surface_create_for_bitmap (connection, bitmap, screen, width, height);
return new XcbSurface (ptr, true);
}
- public override void SetSize (int width, int height)
+ public override void Resize (int width, int height)
{
NativeMethods.cairo_xcb_surface_set_size (Handle, width, height);
}
NativeMethods.cairo_xlib_surface_set_drawable (Handle, drawable, width, height);
}
- public override void SetSize (int width, int height)
+ public override void Resize (int width, int height)
{
NativeMethods.cairo_xlib_surface_set_size (Handle, width, height);
}
namespace Crow.CairoBackend {
- public sealed class SvgHandle : IDisposable {
+ public sealed class SvgHandle : ISvgHandle {
const string lib = "rsvg-2.40";
public IntPtr Raw;
public void SetDpiXY (double dpi_x, double dpi_y) => rsvg_handle_set_dpi_x_y (Raw, dpi_x, dpi_y);
- public void Render(Context cr) =>
+ public void Render(IContext cr) =>
rsvg_handle_render_cairo (Raw, cr == null ? IntPtr.Zero : cr.Handle);
- public void Render (Context cr, string id) =>
+ public void Render (IContext cr, string id) =>
rsvg_handle_render_cairo_sub (Raw, cr == null ? IntPtr.Zero : cr.Handle, id);
[StructLayout(LayoutKind.Sequential)]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFramework>netcoreapp3.0</TargetFramework>
- <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
+ <TargetFramework>netcoreapp3.0</TargetFramework>
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
</PropertyGroup>
- <ItemGroup>
- <Compile Include="src\**\*.cs" />
- </ItemGroup>
+ <ItemGroup>
+ <Compile Include="src\**\*.cs" Exclude="src\VulkanContext.cs" />
+ </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\..\Drawing2D\Drawing2D.csproj" />
- </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="vke" Version="0.2.0-beta" />
+ <ProjectReference Include="..\..\Drawing2D\Drawing2D.csproj" />
+ </ItemGroup>
+
+ <PropertyGroup Condition=" '$(CrowStbSharp)' == 'true'">
+ <DefineConstants>$(DefineConstants);STB_SHARP</DefineConstants>
+ </PropertyGroup>
</Project>
using System;
using System.Text;
using System.Linq;
-using Crow;
+using Drawing2D;
-namespace Crow.Drawing
+namespace Crow.VkvgBackend
{
- public class Context : IDisposable
+ public class Context : IContext
{
IntPtr handle = IntPtr.Zero;
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);
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); }
set { NativeMethods.vkvg_set_fill_rule(handle, value); }
get { return NativeMethods.vkvg_get_fill_rule(handle); }
}
- public FontExtents FontExtents
+ public Drawing2D.FontExtents FontExtents
{
get
{
- FontExtents f_extents;
- NativeMethods.vkvg_font_extents(handle, out f_extents);
- return f_extents;
+ FontExtents e;
+ NativeMethods.vkvg_font_extents(handle, out e);
+ return new Drawing2D.FontExtents (e.Ascent, e.Descent, e.Height, e.MaxXAdvance, e.MaxYAdvance);
}
}
public Antialias Antialias {
set;
get;
}
- public TextExtents TextExtents (ReadOnlySpan<char> s, int tabSize = 4) {
- TextExtents (s, tabSize, out TextExtents extents);
- return extents;
+ 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(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 TextExtents (ReadOnlySpan<char> s, int tabSize, out TextExtents extents) {
- if (s.Length == 0) {
- extents = default;
- return;
- }
- 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 Clear() => NativeMethods.vkvg_clear(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 Save() => NativeMethods.vkvg_save(handle);
+ public void Restore() => NativeMethods.vkvg_restore(handle);
+ public void Flush() => NativeMethods.vkvg_flush(handle);
+ public void Paint() => NativeMethods.vkvg_paint(handle);
+ public void PaintWithAlpha (double alpha) => Paint();
+
+ public void SetFontSize (double size) => NativeMethods.vkvg_set_font_size(handle, (uint)size);
+
+ public void ClosePath() => NativeMethods.vkvg_close_path (handle);
+
+ 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 IntPtr Handle => handle;
+
+ public void AddReference()
+ {
+ NativeMethods.vkvg_reference(handle);
}
- public void TextExtents (Span<byte> bytes, out TextExtents extents) {
- NativeMethods.vkvg_text_extents (handle, ref bytes.GetPinnableReference (), out extents);
+ public uint References() => NativeMethods.vkvg_get_reference_count(handle);
+
+ public string FontFace
+ {
+ set { NativeMethods.vkvg_select_font_face(handle, value); }
}
public Matrix Matrix
{
NativeMethods.vkvg_set_matrix(handle, ref value);
}
}
- public void ShowText (string text) => ShowText (text.AsSpan());
- public void ShowText (ReadOnlySpan<char> s, int tabSize = 4) {
- 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 Rectangle StrokeExtents () => default;
+ 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 ShowText(TextRun textRun)
+
+ public void PushGroup () {
+
+ }
+ public void PopGroupToSource () {
+
+ }
+
+ public void SelectFontFace(string family, FontSlant slant, FontWeight weight)
{
- NativeMethods.vkvg_show_text_run(handle, textRun.Handle);
+ throw new NotImplementedException();
}
- public void Save()
+*/
+ public void MoveTo(float x, float y)
{
- NativeMethods.vkvg_save(handle);
+ NativeMethods.vkvg_move_to(handle, x, y);
}
- public void Restore()
+ public void RelMoveTo(float x, float y)
{
- NativeMethods.vkvg_restore(handle);
+ NativeMethods.vkvg_rel_move_to(handle, x, y);
}
- public void Flush()
+ public void LineTo(float x, float y)
{
- NativeMethods.vkvg_flush(handle);
+ NativeMethods.vkvg_line_to(handle, x, y);
}
- public void Clear()
+ public void LineTo(Point p)
{
- NativeMethods.vkvg_clear(handle);
+ NativeMethods.vkvg_line_to(handle, p.X, p.Y);
}
- public void Paint()
+ public void LineTo(PointD p)
{
- NativeMethods.vkvg_paint(handle);
+ NativeMethods.vkvg_line_to(handle, (float)p.X, (float)p.Y);
}
- public void PaintWithAlpha (double alpha) => Paint();
- public void Arc(float xc, float yc, float radius, float a1, float a2)
+ public void RelLineTo(float x, float y)
{
- NativeMethods.vkvg_arc(handle, xc, yc, radius, a1, a2);
+ NativeMethods.vkvg_rel_line_to(handle, x, y);
}
- public void Arc(double xc, double yc, double radius, double a1, double a2)
+ public void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
{
- NativeMethods.vkvg_arc(handle, (float)xc, (float)yc, (float)radius, (float)a1, (float)a2);
+ NativeMethods.vkvg_curve_to(handle, x1, y1, x2, y2, x3, y3);
}
- public void Arc (PointD center, double radius, double angle1, double angle2)
+ public void RelCurveTo(float x1, float y1, float x2, float y2, float x3, float y3)
{
- NativeMethods.vkvg_arc (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2);
+ NativeMethods.vkvg_rel_curve_to(handle, x1, y1, x2, y2, x3, y3);
}
- public void ArcNegative (PointD center, double radius, double angle1, double angle2)
+ public void MoveTo(double x, double y)
{
- NativeMethods.vkvg_arc_negative (handle, (float)center.X, (float)center.Y, (float)radius, (float)angle1, (float)angle2);
+ NativeMethods.vkvg_move_to(handle, (float)x, (float)y);
}
- public void ArcNegative(float xc, float yc, float radius, float a1, float a2)
+ public void RelMoveTo(double x, double y)
{
- NativeMethods.vkvg_arc_negative(handle, xc, yc, radius, a1, a2);
+ NativeMethods.vkvg_rel_move_to(handle, (float)x, (float)y);
}
- public void Rectangle(float x, float y, float width, float height)
+ public void LineTo(double x, double y)
{
- NativeMethods.vkvg_rectangle(handle, x, y, width, height);
+ NativeMethods.vkvg_line_to(handle, (float)x, (float)y);
}
- public void Scale(float sx, float sy)
+ public void RelLineTo(double x, double y)
{
- NativeMethods.vkvg_scale(handle, sx, sy);
+ NativeMethods.vkvg_rel_line_to(handle, (float)x, (float)y);
}
- public void Translate(float dx, float dy)
+ public void RelCurveTo(double x1, double y1, double x2, double y2, double x3, double y3)
{
- NativeMethods.vkvg_translate(handle, dx, dy);
+ NativeMethods.vkvg_rel_curve_to(handle, (float)x1, (float)y1, (float)x2, (float)y2, (float)x3, (float)y3);
}
- public void Rotate(float alpha)
+
+ public void SetSource(Pattern pat)
{
- NativeMethods.vkvg_rotate(handle, alpha);
+ NativeMethods.vkvg_set_source(handle, pat.Handle);
}
- public void ArcNegative(double xc, double yc, double radius, double a1, double a2)
+ public void SetSource(IPattern pat) {
+ if (pat is Pattern p)
+ NativeMethods.vkvg_set_source (handle, p.Handle);
+ }
+ public void SetSource (Color color)
{
- NativeMethods.vkvg_arc_negative(handle, (float)xc, (float)yc, (float)radius, (float)a1, (float)a2);
+ 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 Rectangle(double x, double y, double width, double height)
+ public void SetSource(ISurface surf, double x = 0, double y = 0)
{
- NativeMethods.vkvg_rectangle(handle, (float)x, (float)y, (float)width, (float)height);
+ NativeMethods.vkvg_set_source_surface(handle, surf.Handle, (float)x, (float)y);
}
+ 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 RenderSvg(IntPtr nsvgImage, string subId = null)
+ {
+ NativeMethods.vkvg_render_svg(handle, nsvgImage, subId);
+ }
+
+ Matrix savedMat = Matrix.Identity;
+ public void SaveTransformations()
+ {
+ NativeMethods.vkvg_get_matrix (handle, out savedMat);
+ }
+
+ public void RestoreTransformations()
+ {
+ NativeMethods.vkvg_set_matrix (handle, ref savedMat);
+ }
+
+ Rectangle IContext.StrokeExtents()
+ {
+ throw new NotImplementedException();
+ }
+
public void Scale(double sx, double sy)
{
NativeMethods.vkvg_scale(handle, (float)sx, (float)sy);
{
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);
{
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);
{
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)
+ public void PopGroupToSource()
{
- 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);
+ throw new NotImplementedException();
}
- 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)
+
+ public void PushGroup()
{
- NativeMethods.vkvg_set_source_surface(handle, surf.Handle, x, y);
+ throw new NotImplementedException();
}
- public void RenderSvg(IntPtr nsvgImage, string subId = null)
+
+ 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 Rectangle(Rectangle r)
+ => NativeMethods.vkvg_rectangle (handle, (float)r.X, (float)r.Y, (float)r.Width, (float)r.Height);
+
+
+ public void SelectFontFace(string family, FontSlant slant, FontWeight weight)
{
- NativeMethods.vkvg_render_svg(handle, nsvgImage, subId);
+ throw new NotImplementedException();
}
- public Crow.Rectangle StrokeExtents () => default;
+
internal static byte[] TerminateUtf8(string s)
{
// compute the byte count including the trailing \0
NativeMethods.vkvg_set_dash(handle, floats, (uint)dashes.Length, (float)offset);
}
}
- 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 Drawing2D.TextExtents TextExtents (ReadOnlySpan<char> s, int tabSize = 4) {
+ TextExtents (s, tabSize, out Drawing2D.TextExtents e);
+ return e;
+ }
+ public void TextExtents (ReadOnlySpan<char> s, int tabSize, out Drawing2D.TextExtents extents) {
+ if (s.Length == 0) {
+ extents = default;
+ return;
}
+ int size = s.Length * 4 + 1;
+ Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ int encodedBytes = s.ToUtf8 (bytes, tabSize);
+ bytes[encodedBytes] = 0;
+ TextExtents (bytes.Slice (0, encodedBytes + 1), out extents);
+ }
+ public void TextExtents (Span<byte> bytes, out Drawing2D.TextExtents extents) {
+ NativeMethods.vkvg_text_extents (handle, ref bytes.GetPinnableReference (), out TextExtents e);
+ extents = new Drawing2D.TextExtents (e.XBearing, e.YBearing, e.Width, e.Height, e.XAdvance, e.YAdvance);
+ }
+ public void ShowText (string text) => ShowText (text.AsSpan());
+ public void ShowText (ReadOnlySpan<char> s, int tabSize = 4) {
+ int size = s.Length * 4 + 1;
+ Span<byte> bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+ int encodedBytes = s.ToUtf8 (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 PushGroup () {
+ public Rectangle StrokeExtents()
+ {
+ throw new NotImplementedException();
}
- 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)
-// Copyright (c) 2018-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2018-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.IO;
+using Drawing2D;
-namespace Crow.Drawing
+namespace Crow.VkvgBackend
{
- public class Device: IDisposable
+ public class Device: IDevice
{
IntPtr handle = IntPtr.Zero;
}
#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 IDevice implementation
+ 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 IRegion CreateRegion() => new Region ();
+
+ public ISurface CreateSurface(int width, int height)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISurface CreateSurface(byte[] data, int width, int height)
+ {
+ throw new NotImplementedException();
+ }
+ public ISurface CreateSurface(IntPtr glfwWinHandle, int width, int height)
+ {
+ throw new NotImplementedException();
+ }
+ public IContext CreateContext(ISurface surf)
+ {
+ throw new NotImplementedException();
+ }
+
+ public IGradient CreateGradient(GradientType gradientType, Rectangle bounds)
+ {
+ throw new NotImplementedException();
+ }
+ public byte[] LoadBitmap (Stream stream, out Size dimensions) {
+ byte[] image;
+#if STB_SHARP
+ StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
+ image = new byte[stbi.Data.Length];
+
+ Array.Copy (stbi.Data, image, stbi.Data.Length);
+ dimensions = new Size (stbi.Width, stbi.Height);
+#else
+ using (StbImage stbi = new StbImage (stream)) {
+ image = new byte [stbi.Size];
+ Marshal.Copy (stbi.Handle, image, 0, stbi.Size);
+ dimensions = new Size (stbi.Width, stbi.Height);
+ }
+#endif
+ return image;
+ }
+
+ public ISvgHandle LoadSvg(Stream stream)
+ {
+ throw new NotImplementedException();
+ }
+
+ public ISvgHandle LoadSvg(string svgFragment)
+ {
+ throw new NotImplementedException();
+ }
+ #endregion
+
+
#region IDisposable implementation
public void Dispose ()
{
--- /dev/null
+// Copyright (c) 2018-2022 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.VkvgBackend
+{
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct FontExtents : IEquatable<FontExtents>
+ {
+ float ascent;
+ float descent;
+ float height;
+ float maxXAdvance;
+ float maxYAdvance;
+
+ public float Ascent {
+ get => ascent;
+ set { ascent = value; }
+ }
+
+ public float Descent {
+ get => descent;
+ set { descent = value; }
+ }
+
+ public float Height {
+ get => height;
+ set { height = value; }
+ }
+
+ public float MaxXAdvance {
+ get => maxXAdvance;
+ set { maxXAdvance = value; }
+ }
+
+ public float MaxYAdvance {
+ get => 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 int GetHashCode () => HashCode.Combine (ascent, descent, height, maxXAdvance, maxYAdvance);
+ public override bool Equals (object obj) => obj is FontExtents fe ? Equals (fe) : false;
+
+ public bool Equals(FontExtents other) =>
+ ascent == other.ascent && descent == other.descent && height == other.height &&
+ maxXAdvance == other.maxXAdvance && maxYAdvance == other.maxYAdvance;
+
+ public static bool operator == (FontExtents extents, FontExtents other) => extents.Equals (other);
+ public static bool operator != (FontExtents extents, FontExtents other) => !extents.Equals (other);
+ }
+}
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-namespace Crow.Drawing
+using Drawing2D;
+
+namespace Crow.VkvgBackend
{
- public class Gradient : Pattern
- {
+ public class Gradient : Pattern, IGradient
+ {
protected Gradient(IntPtr handle) : base (handle) { }
- public void AddColorStop (double offset, Crow.Color c)
+ public void AddColorStop (double offset, Color c)
=> NativeMethods.vkvg_pattern_add_color_stop(handle, (float)offset, c.R / 255f, c.G / 255f, c.B / 255f, c.A / 255f);
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);
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-namespace Crow.Drawing {
+namespace Crow.VkvgBackend {
public struct Matrix {
float xx; float yx;
float xy; float yy;
using System;
using System.Runtime.InteropServices;
+using Drawing2D;
-namespace Crow.Drawing
+namespace Crow.VkvgBackend
{
internal static class NativeMethods
{
[DllImport (libvkvg, CallingConvention = CallingConvention.Cdecl)]
internal static extern void vkvg_set_dash (IntPtr ctx, float[] dashes, uint dashCount, float offset);
+ [DllImport (libvkvg, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void vkvg_path_extents (IntPtr ctx, out float x1, out float y1, out float x2, out float y2);
//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
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-namespace Crow.Drawing
+using Drawing2D;
+
+namespace Crow.VkvgBackend
{
- public class Pattern : IDisposable
+ public class Pattern : IPattern
{
protected IntPtr handle = IntPtr.Zero;
+ public IntPtr Handle => handle;
#region CTORS & DTOR
protected Pattern(IntPtr handle)
}
public uint References() => NativeMethods.vkvg_pattern_get_reference_count(handle);
- public IntPtr Handle => handle;
public Extend Extend
{
+ get => NativeMethods.vkvg_pattern_get_extend(handle);
set { NativeMethods.vkvg_pattern_set_extend(handle, value); }
- get { return NativeMethods.vkvg_pattern_get_extend(handle); }
}
public Filter Filter
{
+ get => NativeMethods.vkvg_pattern_get_filter(handle);
set { NativeMethods.vkvg_pattern_set_filter(handle, value); }
- get { return NativeMethods.vkvg_pattern_get_filter(handle); }
}
#region IDisposable implementation
--- /dev/null
+// 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 Drawing2D;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Crow.VkvgBackend {
+ public class Region : IRegion
+ {
+ Rectangle _bounds;
+ bool boundsUpToDate = true;
+ public List<Rectangle> list = new List<Rectangle>();
+ public int count => list.Count;
+
+ public void AddRectangle(Rectangle r)
+ {
+ if (r == default)
+ return;
+ if (DoesNotContains (r)) {
+ list.Add (r);
+ boundsUpToDate = false;
+ }
+ }
+ public bool DoesNotContains(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.ContainsOrIsEqual(r))
+ return false;
+ return true;
+ }
+ public bool intersect(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return true;
+ return false;
+ }
+ public void stroke(IContext ctx, Color c)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+
+ ctx.SetSource(c);
+
+ ctx.LineWidth = 2;
+ ctx.Stroke ();
+ }
+ public void clearAndClip(IContext 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(IContext ctx)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+
+ ctx.Clip();
+ }
+ 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(IContext ctx)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ }
+
+ #region IRegion implemenatation
+ public bool IsEmpty => list.Count == 0;
+ public int NumRectangles => list.Count;
+ public Rectangle GetRectangle(int i) => list[i];
+ public void UnionRectangle (Rectangle r) {
+ /*if (r == default)
+ System.Diagnostics.Debugger.Break ();*/
+ AddRectangle (r);
+ }
+ public bool OverlapOut (Rectangle r) {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return false;
+ return true;
+ }
+ public RegionOverlap Contains(Rectangle rectangle)
+ {
+ throw new NotImplementedException();
+ }
+ public void Reset()
+ {
+ list = new List<Rectangle>();
+ _bounds = default;
+ boundsUpToDate = true;
+ }
+
+ public bool Equals([AllowNull] IRegion other)
+ => other is Region r ? Bounds.Equals (r.Bounds) : false;
+ #endregion
+
+ public override string ToString ()
+ {
+ string tmp = "";
+ foreach (Rectangle r in list) {
+ tmp += r.ToString ();
+ }
+ return tmp;
+ }
+
+ public void Dispose()
+ {
+
+ }
+
+ }
+}
-// Copyright (c) 2018-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2018-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 Drawing2D;
-namespace Crow.Drawing
+namespace Crow.VkvgBackend
{
- public class Surface: IDisposable
- {
+ public class Surface: ISurface
+ {
IntPtr handle = IntPtr.Zero;
Device vkvgDev;
+ #region CTOR
public Surface (Device device, int width, int height)
{
vkvgDev = device;
- if (width <= 0 || height <= 0)
+ 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);
{
handle = NativeMethods.vkvg_surface_create (devHandle, (uint)width, (uint)heigth);
}
+ #endregion
~Surface ()
{
Dispose (false);
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 ISurface CreateSimilar(int width, int height) => new Surface (vkvgDev, width, height);
+
+ public void Resize(int width, int height)
+ {
+ throw new NotImplementedException();
+ }
public void Flush () {
//throw new NotImplementedException ();
-//Copyright GPL2
-using System;
+// 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)
-namespace Crow.Drawing {
+using System;
+using Drawing2D;
+namespace Crow.VkvgBackend
+{
+ public sealed class SvgHandle : ISvgHandle {
- public sealed class SvgHandle : IDisposable {
+ IntPtr handle;
- public IntPtr Raw;
-
- public SvgHandle (Device dev, Span<byte> bytes)
+ 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());
+ handle = NativeMethods.nsvg_load (dev.Handle, ref bytes.GetPinnableReference());
}
public SvgHandle (Device dev, string file_name)
- {
- Raw = NativeMethods.nsvg_load_file (dev.Handle, file_name);
+ {
+ handle = 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 void Render(IContext cr) =>
+ cr.RenderSvg (handle);
+
+ public void Render (IContext cr, string id) =>
+ cr.RenderSvg (handle, id);
+
public Size Dimensions {
get {
- NativeMethods.nsvg_get_size (Raw, out int w, out int h);
+ NativeMethods.nsvg_get_size (handle, out int w, out int h);
return new Size (w, h);
}
}
-
- public void Dispose() {
- NativeMethods.nsvg_destroy (Raw);
+ public void Dispose() {
+ NativeMethods.nsvg_destroy (handle);
}
}
--- /dev/null
+// Copyright (c) 2018-2022 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.VkvgBackend
+{
+ [StructLayout (LayoutKind.Sequential)]
+ internal struct TextExtents : IEquatable<TextExtents>
+ {
+ float xBearing;
+ float yBearing;
+ float width;
+ float height;
+ float xAdvance;
+ float yAdvance;
+
+ public float XBearing {
+ get => xBearing;
+ set { xBearing = value; }
+ }
+
+ public float YBearing {
+ get => yBearing;
+ set { yBearing = value; }
+ }
+
+ public float Width {
+ get => width;
+ set { width = value; }
+ }
+
+ public float Height {
+ get => height;
+ set { height = value; }
+ }
+
+ public float XAdvance {
+ get => xAdvance;
+ set { xAdvance = value; }
+ }
+
+ public float YAdvance {
+ get => yAdvance;
+ set { yAdvance = value; }
+ }
+
+ public override int GetHashCode () =>
+ HashCode.Combine (xBearing, yBearing, width, height, xAdvance, yAdvance);
+ public override bool Equals (object obj) => obj is TextExtents te ? Equals (te) : false;
+
+ public bool Equals(TextExtents other) =>
+ xBearing == other.xBearing && yBearing == other.yBearing && width == other.width && height == other.height &&
+ xAdvance == other.xAdvance && yAdvance == other.yAdvance;
+ public static bool operator == (TextExtents extents, TextExtents other) => extents.Equals (other);
+ public static bool operator != (TextExtents extents, TextExtents other )=> !extents.Equals (other);
+ }
+}
-// Copyright (c) 2018-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+// Copyright (c) 2018-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;
-namespace Crow.Drawing {
+using Drawing2D;
+
+namespace Crow.VkvgBackend
+{
public class TextRun : IDisposable {
IntPtr handle = IntPtr.Zero;
public IntPtr Handle { get { return handle; } }
- public TextExtents Extents {
+ public Drawing2D.TextExtents Extents {
get {
- TextExtents extents;
- NativeMethods.vkvg_text_run_get_extents (handle, out extents);
- return extents;
+ NativeMethods.vkvg_text_run_get_extents (handle, out TextExtents e);
+ return new Drawing2D.TextExtents (e.XBearing, e.YBearing, e.Width, e.Height, e.XAdvance, e.YAdvance);
}
}
+++ /dev/null
-//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 ;
- }
- }
-}
-
+++ /dev/null
-// 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;
-
-
-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()
- {
-
- }
- }
-}
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CairoBackend", "Backends\CairoBackend\CairoBackend.csproj", "{E06441A9-0CFD-45BB-9478-99D28CEB327F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VkvgBackend", "Backends\VkvgBackend\VkvgBackend.csproj", "{34976828-80CF-4AC5-8C81-F66F635DC5FC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
{E06441A9-0CFD-45BB-9478-99D28CEB327F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E06441A9-0CFD-45BB-9478-99D28CEB327F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E06441A9-0CFD-45BB-9478-99D28CEB327F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {34976828-80CF-4AC5-8C81-F66F635DC5FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {34976828-80CF-4AC5-8C81-F66F635DC5FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {34976828-80CF-4AC5-8C81-F66F635DC5FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {34976828-80CF-4AC5-8C81-F66F635DC5FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
{56329D48-D382-4850-93DE-59C453894E8A} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{18EBB41F-815E-4BF5-B80F-C9E2FAB2993A} = {B2C7855A-2878-47FD-AD32-9A83DB4AB8C6}
{E06441A9-0CFD-45BB-9478-99D28CEB327F} = {451F5727-2A2E-4361-A41B-089429ADE8F9}
+ {34976828-80CF-4AC5-8C81-F66F635DC5FC} = {451F5727-2A2E-4361-A41B-089429ADE8F9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {00D4E149-7131-49F4-BAAD-559AA961A78E}
<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\GraphicBackends\**\*.*" />
+ <Compile Include="src\**\*.cs" />
<EmbeddedResource Include="Templates\*.*">
<LogicalName>Crow.%(Filename)%(Extension)</LogicalName>
</EmbeddedResource>
<ItemGroup>
<ProjectReference Include="..\Drawing2D\Drawing2D.csproj" />
+ <ProjectReference Include="..\Backends\CairoBackend\CairoBackend.csproj" />
</ItemGroup>
+
+ <PropertyGroup Condition=" '$(CrowStbSharp)' == 'true'">
+ <DefineConstants>$(DefineConstants);STB_SHARP</DefineConstants>
+ </PropertyGroup>
+
</Project>
return;
}
using (Stream stream = iFace.GetStreamFromPath (Path)) {
- load (stream);
- //loadBitmap (new System.Drawing.Bitmap (stream));
+ image = iFace.Device.LoadBitmap (stream, out Size dimensions);
+ Dimensions = dimensions;
iFace.sharedPictures[Path] = new sharedPicture (image, Dimensions);
}
}
- void load (Stream stream) {
-#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];
- image[i + 1] = stbi.Data[i + 1];
- 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];
- #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
- }
- internal static sharedPicture CreateSharedPicture (Stream stream) {
- BmpPicture pic = new BmpPicture ();
- pic.load (stream);
- return new sharedPicture (pic.image, pic.Dimensions);
- }
-
//load image via System.Drawing.Bitmap, cairo load png only
/*void loadBitmap (System.Drawing.Bitmap bitmap)
if (image == null)
load (iFace);
- float widthRatio = 1f;
- float heightRatio = 1f;
+ double widthRatio = 1;
+ double heightRatio = 1;
if (Scaled){
- widthRatio = (float)rect.Width / Dimensions.Width;
- heightRatio = (float)rect.Height / Dimensions.Height;
+ widthRatio = (double)rect.Width / Dimensions.Width;
+ heightRatio = (double)rect.Height / Dimensions.Height;
}
if (KeepProportions) {
widthRatio = heightRatio;
}
- //gr.Save ();
-
- Matrix m = gr.Matrix;
+ gr.SaveTransformations ();
gr.Translate (rect.Left,rect.Top);
gr.Scale (widthRatio, heightRatio);
gr.Translate ((rect.Width/widthRatio - Dimensions.Width)/2, (rect.Height/heightRatio - Dimensions.Height)/2);
-#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
- {
+ using (ISurface imgSurf = iFace.Device.CreateSurface (image, Dimensions.Width, Dimensions.Height)) {
gr.SetSource (imgSurf, 0,0);
gr.Paint ();
}
- gr.Matrix = m;
- //gr.Restore ();
+ gr.RestoreTransformations ();
}
}
}
{
public class Gradient : Fill
{
- public enum Type
- {
- Vertical,
- Horizontal,
- Oblic,
- Radial
- }
public class ColorStop
{
public double Offset;
return new ColorStop (-1, Color.FromIml (parts [0]));
}
}
- public Type GradientType = Type.Vertical;
+ public GradientType Type = GradientType.Vertical;
// public double x0;
// public double y0;
// public double x1;
// public double Radius1;
// public double Radius2;
public List<ColorStop> Stops = new List<ColorStop>();
- public Gradient(Type _type)
+ public Gradient(GradientType _type)
{
- GradientType = _type;
+ Type = _type;
}
#region implemented abstract members of Fill
public override void SetAsSource (Interface iFace, IContext ctx, Rectangle bounds = default(Rectangle))
{
- Crow.Drawing.Gradient grad = null;
- switch (GradientType) {
- case Type.Vertical:
- grad = new LinearGradient (bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);
- break;
- case Type.Horizontal:
- grad = new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Top);
- break;
- case Type.Oblic:
- grad = new LinearGradient (bounds.Left, bounds.Top, bounds.Right, bounds.Bottom);
- break;
- case Type.Radial:
- throw new NotImplementedException ();
- }
-
+ IGradient grad = iFace.Device.CreateGradient (Type, bounds);
foreach (ColorStop cs in Stops) {
if (cs == null)
continue;
switch (stops[0].Trim()) {
case "vgradient":
- tmp = new Gradient (Type.Vertical);
+ tmp = new Gradient (GradientType.Vertical);
break;
case "hgradient":
- tmp = new Gradient (Type.Horizontal);
+ tmp = new Gradient (GradientType.Horizontal);
break;
case "ogradient":
- tmp = new Gradient (Type.Oblic);
+ tmp = new Gradient (GradientType.Oblic);
break;
default:
throw new Exception ("Unknown gradient type: " + stops [0]);
/// </summary>
public class SvgPicture : Picture
{
- SvgHandle hSVG;
+ ISvgHandle hSVG;
#region CTOR
/// <summary>
{
if (iFace.sharedPictures.ContainsKey (Path)) {
sharedPicture sp = iFace.sharedPictures [Path];
- hSVG = (SvgHandle)sp.Data;
+ hSVG = (ISvgHandle)sp.Data;
Dimensions = sp.Dims;
return;
}
using (Stream stream = iFace.GetStreamFromPath (Path))
- load (iFace, stream);
+ hSVG = iFace.Device.LoadSvg (stream);
+ Dimensions = hSVG.Dimensions;
iFace.sharedPictures [Path] = new sharedPicture (hSVG, Dimensions);
}
- void load (Interface iface, Stream stream) {
- using (BinaryReader sr = new BinaryReader (stream)) {
-#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 (Interface iface, Stream stream) {
- SvgPicture pic = new SvgPicture ();
- pic.load (iface, stream);
- return new sharedPicture (pic.hSVG, pic.Dimensions);
- }
- 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);
+ public void LoadSvgFragment (Interface iface, string fragment) {
+ hSVG = iface.Device.LoadSvg (fragment);
+ Dimensions = hSVG.Dimensions;
}
#region implemented abstract members of Fill
widthRatio = heightRatio;
}
-#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 (IContext gr = new Context (tmp)) {
+ using (ISurface tmp = iFace.Device.CreateSurface (bounds.Width, bounds.Height)) {
+ using (IContext gr = iFace.Device.CreateContext (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);
else
widthRatio = heightRatio;
}
-
+
gr.Save ();
gr.Translate (rect.Left,rect.Top);
hSVG.Render (gr);
else {
string[] parts = subPart.Split (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- foreach (string p in parts)
+ foreach (string p in parts)
hSVG.Render (gr, "#" + subPart);
}
-
+
gr.Restore ();
}
}
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
-
+using Drawing2D;
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
/// Create the VulkanContext with swapchain support. Override it to use another vulkan backend.
/// </summary>
#endif
+ static string backendDeviceTypeString = "Crow.CairoBackend.Device";
protected void initBackend (bool offscreen = false) {
-#if VKVG
- if (offscreen)
- vkCtx = new OffscreenVulkanContext (this);
- else
- vkCtx = new VulkanContext (this, hWin, (uint)clientRectangle.Width, (uint)clientRectangle.Height);
-#endif
+
+ dev = new Crow.CairoBackend.Device ();
+ clipping = dev.CreateRegion ();
}
/// <summary>
/// Create the main rendering surface. The default is a GLFW window with a cairo surface bound to it.
registerGlfwCallbacks ();
-#if VKVG
initBackend ();
- vkCtx.CreateSurface (clientRectangle.Width, clientRectangle.Height, ref surf);
-#else
-#endif
+ CreateMainSurface (ref clientRectangle);
}
/// <summary>
/// ??
/// <param name="r"></param>
public void CreateMainSurface (ref Rectangle r) {
surf?.Dispose();
-#if (VKVG)
- vkCtx.CreateSurface (clientRectangle.Width, clientRectangle.Height, ref surf);
-#else
- surf = new ImageSurface (Format.ARGB32, r.Width, r.Height);
-#endif
+ surf = Device.CreateSurface (hWin, r.Width, r.Height);
}
public IntPtr SurfacePointer {
get {
if (disposing)
{
disposeContextMenus ();
-#if VKVG
- vkCtx.Dispose ();
-#endif
+ dev.Dispose ();
}
currentCursor?.Dispose ();
/// <summary>Client rectangle in the host context</summary>
protected Rectangle clientRectangle;
/// <summary>Clipping rectangles on the root context</summary>
- Region clipping = new Region();
+ IRegion clipping;
/// <summary>Main Cairo context</summary>
//Context ctx;
#endregion
foreach (string pic in Directory.GetFiles (path, "*.*", SearchOption.AllDirectories)) {
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 (this, s);
- else
- sharedPictures[resId] = BmpPicture.CreateSharedPicture (s);
+ if (resId.EndsWith (".svg", StringComparison.OrdinalIgnoreCase)) {
+ ISvgHandle hSVG = Device.LoadSvg (s);
+ sharedPictures[resId] = new sharedPicture (hSVG, hSVG.Dimensions);
+ } else {
+ byte[] image = Device.LoadBitmap (s, out Size dimensions);
+ sharedPictures[resId] = new sharedPicture (image, dimensions);
+ }
}
}
}
if (!clipping.IsEmpty || shouldDrawTextCursor) {
if (ctx == null) {
- using (ctx = new Context (surf))
+ using (ctx = Device.CreateContext (surf))
processDrawing (ctx);
}else
processDrawing (ctx);
}
-
-#if VKVG
- if (IsDirty) {
- if (!vkCtx.render ())
- ProcessResize (new Rectangle (0,0,(int)vkCtx.width, (int)vkCtx.height));
- }
-#endif
} finally {
PerformanceMeasure.End (PerformanceMeasure.Kind.Update);
PerformanceMeasure.Notify ();
}
-#if VKVG
- void resizeVulkanContext () {
-
-
-
- }
-#endif
/// <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>
public virtual void ProcessResize(Rectangle bounds){
lock (UpdateMutex) {
clientRectangle = bounds;
-
-#if VKVG
- vkCtx.CreateSurface (clientRectangle.Width, clientRectangle.Height, ref surf);
-#else
- switch (Environment.OSVersion.Platform) {
- case PlatformID.MacOSX:
- break;
- case PlatformID.Unix:
- surf.SetSize (clientRectangle.Width, clientRectangle.Height);
- break;
- case PlatformID.Win32NT:
- case PlatformID.Win32S:
- case PlatformID.Win32Windows:
- if (ownWindow) {
- surf.Dispose ();
- IntPtr hWin32 = Glfw3.GetWin32Window (hWin);
- IntPtr hdc = Glfw3.GetWin32DC (hWin32);
- surf = new Win32Surface (hdc);
- }else
- surf.SetSize (clientRectangle.Width, clientRectangle.Height);
- break;
- case PlatformID.Xbox:
- case PlatformID.WinCE:
- throw new PlatformNotSupportedException ("Unable to create cairo surface.");
- }
-#endif
+ surf.Resize (clientRectangle.Width, clientRectangle.Height);
foreach (Widget g in GraphicTree)
g.RegisterForLayouting (LayoutingType.All);
#region CTOR
public LayoutingQueueItem (LayoutingType _layoutType, ILayoutable _graphicObject)
- {
+ {
LayoutType = _layoutType;
Layoutable = _graphicObject;
Layoutable.RegisteredLayoutings |= LayoutType;
if (!go.layoutMutex.TryEnterWriteLock (1)) {
go.IFace.LayoutingQueue.Enqueue (this);
-#if DEBUG_LOG
+#if DEBUG_LOG
result = Result.Requeued;
#endif
return;
Slot = Layoutable.getSlot ();
#endif
LayoutingTries++;
-
+
if (Layoutable.UpdateLayout (LayoutType)) {
Layoutable.RequiredLayoutings &= (~LayoutType);
- if (Layoutable.RequiredLayoutings == LayoutingType.None && go.IsDirty)
+ if (Layoutable.RequiredLayoutings == LayoutingType.None && go.IsDirty)
go.IFace.EnqueueForRepaint (this);
-#if DEBUG_LOG
+#if DEBUG_LOG
result = Result.Success;
#endif
} else {
}
#endif
}
-#if DEBUG_LOG
+#if DEBUG_LOG
NewSlot = Layoutable.getSlot();
#endif
} finally {
+++ /dev/null
-// 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.Collections.Generic;
-using System.Text;
-
-namespace Crow.Text
-{
- public class Encoding
- {
- public static int ToUtf8 (ReadOnlySpan<char> source, Span<byte> buff, int tabWidth = 4) {
- int c = 0;
- int encodedBytes = 0;
- int encodedChar = 0;
- while (c < source.Length) {
- if (source[c] < 0xD800) {
- if (source[c] == '\t') {
- int encTabWidth = tabWidth - encodedChar % tabWidth;
- for (int i = 0; i < encTabWidth; i++) {
- buff[encodedBytes++] = 0x20;
- encodedChar++;
- }
- c++;
- continue;
- }
-
- if (source[c] < 0x80) { //1 byte
- buff[encodedBytes++] = (byte)source[c++];
- }else if (source[c] < 0x7FF) { //2 bytes
- buff[encodedBytes++] = (byte)((source[c] >> 6) + 0xC0);
- buff[encodedBytes++] = (byte)((source[c] & 0x3F) + 0x80);
- c++;
- } else { //3 bytes
- //ushort ch = (ushort)(source[c] - 0x10000u);
- buff[encodedBytes++] = (byte)((source[c] >> 12) + 0xE0);
- buff[encodedBytes++] = (byte)((source[c] >> 6) & 0x00BF);
- buff[encodedBytes++] = (byte)((source[c] & 0x3F) + 0x80);
- c++;
- }
-
- encodedChar++;
- continue;
- }
- throw new NotImplementedException();
- }
- buff[encodedBytes] = 0;
- return encodedBytes;
- }
-
-
- /*unsafe static int Utf16toUtf8 (byte* cptr, byte* buff, int tabWidth) {
-
- }*/
- }
-}
r.Height -= 4;
r.Y += 2;
- Gradient.Type gt = Gradient.Type.Horizontal;
- if (Orientation == Orientation.Vertical)
- gt = Gradient.Type.Vertical;
-
- Gradient grad = new Gradient (gt);
+ Gradient grad = new Gradient (
+ Orientation == Orientation.Vertical ? GradientType.Vertical : GradientType.Horizontal);
Color c = currentColor;
switch (component) {
CairoHelpers.CairoRectangle (gr, r, CornerRadius);
gr.Fill ();
-
-
r = ClientRectangle;
switch (cursorType) {
r.Height -= 4;
r.Y += 2;
- Gradient.Type gt = Gradient.Type.Horizontal;
- if (Orientation == Orientation.Vertical)
- gt = Gradient.Type.Vertical;
-
- Gradient grad = new Gradient (gt);
+ Gradient grad = new Gradient (
+ Orientation == Orientation.Vertical ? GradientType.Vertical : GradientType.Horizontal);
grad.Stops.Add (new Gradient.ColorStop (0, new Color (1, 0, 0, 1)));
grad.Stops.Add (new Gradient.ColorStop (0.167, new Color (1, 1, 0, 1)));
using System.Xml.Serialization;
using System.ComponentModel;
using System.Diagnostics;
-
-
+using Drawing2D;
namespace Crow
{
gr.Operator = Operator.Over;
}
}
- #endregion
+ #endregion
}
}
if (bytes.Length < size)
bytes = size > 512 ? new byte[size] : stackalloc byte[size];
- encodedBytes = Crow.Text.Encoding.ToUtf8 (_text.GetLine (lines[i]), bytes);
+ encodedBytes = _text.GetLine (lines[i]).ToUtf8 (bytes);
bytes[encodedBytes++] = 0;
if (lines[i].LengthInPixel < 0) {
Span<byte> bytes = stackalloc byte[5];//utf8 single char buffer + '\0'
for (int i = 0; i < ls.Length; i++) {
- int encodedBytes = Crow.Text.Encoding.ToUtf8 (curLine.Slice (i, 1), bytes);
+ int encodedBytes = curLine.Slice (i, 1).ToUtf8 (bytes);
bytes[encodedBytes] = 0;
gr.TextExtents (bytes, out te);
gr.Fill ();
}
- Crow.Gradient grad = new Gradient (Gradient.Type.Horizontal);
+ Crow.Gradient grad = new Gradient (GradientType.Horizontal);
grad.Stops.Add (new Gradient.ColorStop (0, new Color (1, 1, 1, 1)));
grad.Stops.Add (new Gradient.ColorStop (1, new Color (1, 1, 1, 0)));
grad.SetAsSource (IFace, gr, r);
CairoHelpers.CairoRectangle (gr, r, CornerRadius);
gr.Fill();
- grad = new Gradient (Gradient.Type.Vertical);
+ grad = new Gradient (GradientType.Vertical);
grad.Stops.Add (new Gradient.ColorStop (0, new Color (0, 0, 0, 0)));
grad.Stops.Add (new Gradient.ColorStop (1, new Color (0, 0, 0, 1)));
grad.SetAsSource (IFace, gr, r);
return;
Rectangle cr = ClientRectangle;
- double widthRatio = 1f, heightRatio = 1f;
+ double widthRatio = 1, heightRatio = 1;
double w = (double)(contentSize.Width == 0 ? size.Width : contentSize.Width);
double h = (double)(contentSize.Height == 0 ? size.Height : contentSize.Height);
widthRatio = heightRatio;
}
- Matrix m = gr.Matrix;
- //gr.Save ();
+ gr.SaveTransformations ();
gr.Translate (cr.Left, cr.Top);
gr.Scale (widthRatio, heightRatio);
using (PathParser parser = new PathParser (path))
parser.Draw (gr);
- //gr.Restore ();
- gr.Matrix = m;
+ gr.RestoreTransformations ();
}
/// are repeated at each cached levels of the tree with correspondig coordinate system. This is done
/// in a dedicated step of the update between layouting and drawing.
/// </summary>
- public Region Clipping;
+ public IRegion Clipping;
#region IValueChange implementation
/// <summary>
/// action.
/// </summary>
protected Widget () {
- Clipping = new Region ();
#if DEBUG_STATS
TotalWidgetCreated++;
#endif
{
DbgLogger.StartEvent (DbgEvtType.GOInitialization, this);
+ Clipping = IFace.Device.CreateRegion ();
Type thisType = this.GetType ();
if (!string.IsNullOrEmpty (style)) {
}
#endregion
- protected void setFontForContext (IContext gr) {
-
- }
-
#region Rendering
/// <summary> This is the common overridable drawing routine to create new widget </summary>
protected virtual void onDraw(IContext gr)
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 = IFace.Device.CreateSurface (Slot.Width, Slot.Height);
+
//bmp = new ImageSurface(Format.Argb32, Slot.Width, Slot.Height);
DbgLogger.StartEvent (DbgEvtType.GOCreateContext, this);
--- /dev/null
+// 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;
+
+namespace Drawing2D
+{
+ public static class Extensions
+ {
+ public static int ToUtf8 (this ReadOnlySpan<char> source, Span<byte> buff, int tabWidth = 4) {
+ int c = 0;
+ int encodedBytes = 0;
+ int encodedChar = 0;
+ while (c < source.Length) {
+ if (source[c] < 0xD800) {
+ if (source[c] == '\t') {
+ int encTabWidth = tabWidth - encodedChar % tabWidth;
+ for (int i = 0; i < encTabWidth; i++) {
+ buff[encodedBytes++] = 0x20;
+ encodedChar++;
+ }
+ c++;
+ continue;
+ }
+
+ if (source[c] < 0x80) { //1 byte
+ buff[encodedBytes++] = (byte)source[c++];
+ }else if (source[c] < 0x7FF) { //2 bytes
+ buff[encodedBytes++] = (byte)((source[c] >> 6) + 0xC0);
+ buff[encodedBytes++] = (byte)((source[c] & 0x3F) + 0x80);
+ c++;
+ } else { //3 bytes
+ //ushort ch = (ushort)(source[c] - 0x10000u);
+ buff[encodedBytes++] = (byte)((source[c] >> 12) + 0xE0);
+ buff[encodedBytes++] = (byte)((source[c] >> 6) & 0x00BF);
+ buff[encodedBytes++] = (byte)((source[c] & 0x3F) + 0x80);
+ c++;
+ }
+
+ encodedChar++;
+ continue;
+ }
+ throw new NotImplementedException();
+ }
+ buff[encodedBytes] = 0;
+ return encodedBytes;
+ }
+
+
+ /*unsafe static int Utf16toUtf8 (byte* cptr, byte* buff, int tabWidth) {
+
+ }*/
+ }
+}
Mesh,
RasterSource,
}
+ public enum GradientType
+ {
+ Vertical,
+ Horizontal,
+ Oblic,
+ Radial
+ }
public enum Operator
{
[StructLayout (LayoutKind.Sequential)]
public struct FontExtents : IEquatable<FontExtents>
{
- float ascent;
- float descent;
- float height;
- float maxXAdvance;
- float maxYAdvance;
+ double ascent;
+ double descent;
+ double height;
+ double maxXAdvance;
+ double maxYAdvance;
- public float Ascent {
+ public double Ascent {
get => ascent;
set { ascent = value; }
}
- public float Descent {
+ public double Descent {
get => descent;
set { descent = value; }
}
- public float Height {
+ public double Height {
get => height;
set { height = value; }
}
- public float MaxXAdvance {
+ public double MaxXAdvance {
get => maxXAdvance;
set { maxXAdvance = value; }
}
- public float MaxYAdvance {
+ public double MaxYAdvance {
get => maxYAdvance;
set { maxYAdvance = value; }
}
- public FontExtents (float ascent, float descent, float height, float maxXAdvance, float maxYAdvance)
+ public FontExtents (double ascent, double descent, double height, double maxXAdvance, double maxYAdvance)
{
this.ascent = ascent;
this.descent = descent;
FillRule FillRule { get; set; }
FontExtents FontExtents { get; }
Antialias Antialias { get; set; }
+ void SetDash (double [] dashes, double offset = 0);
+
TextExtents TextExtents (ReadOnlySpan<char> s, int tabSize = 4);
void TextExtents (ReadOnlySpan<char> s, int tabSize, out TextExtents extents);
void TextExtents (Span<byte> bytes, out TextExtents extents);
- Matrix Matrix { get; set; }
void ShowText (string text);
void ShowText (ReadOnlySpan<char> s, int tabSize = 4);
void ShowText (Span<byte> bytes);
+
void Save();
void Restore();
- void Flush();
- void Clear();
- void Paint();
- void PaintWithAlpha (double alpha);
-
- void Arc(float xc, float yc, float radius, float a1, float a2);
- void Arc(double xc, double yc, double radius, double a1, double a2);
- void Arc (PointD center, double radius, double angle1, double angle2);
- void ArcNegative (PointD center, double radius, double angle1, double angle2);
- void ArcNegative(float xc, float yc, float radius, float a1, float a2);
- void Rectangle(float x, float y, float width, float height);
- void Scale(float sx, float sy);
- void Translate(float dx, float dy);
- void Rotate(float alpha);
- void ArcNegative(double xc, double yc, double radius, double a1, double a2);
- void Rectangle(double x, double y, double width, double height);
+ void SaveTransformations ();
+ void RestoreTransformations ();
void Scale(double sx, double sy);
void Translate(double dx, double dy);
void Translate(PointD p);
void Rotate(double alpha);
- void Fill();
- void FillPreserve();
- void Stroke();
- void StrokePreserve();
- void Clip();
- void ClipPreserve();
- void ResetClip();
+
+ void Flush();
+ void Clear();
+
void NewPath();
void NewSubPath();
void ClosePath();
- void MoveTo(PointD p);
+ void Arc(double xc, double yc, double radius, double a1, double a2);
+ void Arc (PointD center, double radius, double angle1, double angle2);
+ void ArcNegative(double xc, double yc, double radius, double a1, double a2);
+ void ArcNegative (PointD center, double radius, double angle1, double angle2);
void MoveTo(Point p);
- void MoveTo(float x, float y);
- void RelMoveTo(float x, float y);
- void LineTo(float x, float y);
- void LineTo(Point p);
- void LineTo(PointD p);
- void RelLineTo(float x, float y);
- void CurveTo(float x1, float y1, float x2, float y2, float x3, float y3);
- void RelCurveTo(float x1, float y1, float x2, float y2, float x3, float y3);
+ void MoveTo(PointD p);
void MoveTo(double x, double y);
void RelMoveTo(double x, double y);
void LineTo(double x, double y);
+ void LineTo(Point p);
+ void LineTo(PointD p);
void RelLineTo(double x, double y);
void CurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
void RelCurveTo(double x1, double y1, double x2, double y2, double x3, double y3);
+ void Rectangle(double x, double y, double width, double height);
+ void Rectangle(Rectangle r);
+
+ void Paint();
+ void PaintWithAlpha (double alpha);
+ void Fill();
+ void FillPreserve();
+ Rectangle StrokeExtents ();
+ void Stroke();
+ void StrokePreserve();
+ void Clip();
+ void ClipPreserve();
+ void ResetClip();
+
void SetSource(IPattern pat);
void SetSource (Color color);
- void SetSource(float r, float g, float b, float a = 1f);
void SetSource(double r, double g, double b, double a = 1.0);
- void SetSource(ISurface surf, float x = 0f, float y = 0f);
- void SetSourceSurface(ISurface surf, float x = 0f, float y = 0f);
+ void SetSource(ISurface surf, double x = 0f, double y = 0f);
void RenderSvg(IntPtr svgNativeHandle, string subId = null);
- Rectangle StrokeExtents ();
- void SetDash (double [] dashes, double offset = 0);
- float[] Dashes { set; }
- //void PushGroup ();
- //void PopGroupToSource ();
+ void PushGroup ();
+ void PopGroupToSource ();
}
}
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
using System;
+using System.IO;
namespace Drawing2D
{
void GetDpy (out int hdpy, out int vdpy);
void SetDpy (int hdpy, int vdpy);
+ IRegion CreateRegion ();
ISurface CreateSurface (int width, int height);
-
+ ISurface CreateSurface (byte[] data, int width, int height);
+ ISurface CreateSurface (IntPtr glfwWinHandle, int width, int height);
IContext CreateContext (ISurface surf);
+ //IPattern CreatePattern (PatternType patternType);
+ IGradient CreateGradient (GradientType gradientType, Rectangle bounds);
+ byte[] LoadBitmap (Stream stream, out Size dimensions);
+ ISvgHandle LoadSvg (Stream stream);
+ ISvgHandle LoadSvg (string svgFragment);
}
}
--- /dev/null
+// 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)
+
+namespace Drawing2D
+{
+ public interface IGradient : IPattern
+ {
+ void AddColorStop (double offset, Color c);
+ void AddColorStop(float offset, float r, float g, float b, float a = 1f);
+ }
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 2022 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 Drawing2D
+{
+ public interface IPattern : IDisposable
+ {
+ IntPtr Handle { get; }
+ Extend Extend { get; set; }
+ Filter Filter { get; set; }
+ }
+}
\ No newline at end of file
--- /dev/null
+// Copyright (c) 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;
+
+namespace Drawing2D
+{
+ public enum RegionOverlap {
+ In,
+ Out,
+ Part,
+ }
+
+ public interface IRegion : IDisposable, IEquatable<IRegion>
+ {
+ bool IsEmpty { get; }
+ int NumRectangles { get; }
+ Rectangle GetRectangle (int nth);
+ void UnionRectangle (Rectangle r);
+ bool OverlapOut (Rectangle r);
+ RegionOverlap Contains (Rectangle rectangle);
+ void Reset ();
+ }
+}
void WriteTo (IntPtr bitmap);
void Clear ();
ISurface CreateSimilar (int width, int height);
+ void Resize (int width, int height);
}
}
--- /dev/null
+//Copyright GPL2
+using System;
+using System.Runtime.InteropServices;
+
+namespace Drawing2D {
+
+
+ public interface ISvgHandle : IDisposable {
+ void Render(IContext cr);
+ void Render (IContext cr, string id);
+
+ Size Dimensions { get; }
+ }
+}
+++ /dev/null
-// Copyright (c) 2022 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 Drawing2D
-{
- public interface IPattern : IDisposable
- {
- Extend Extend { get; set; }
- Filter Filter { get; set; }
- }
-}
\ No newline at end of file
[StructLayout (LayoutKind.Sequential)]
public struct TextExtents : IEquatable<TextExtents>
{
- float xBearing;
- float yBearing;
- float width;
- float height;
- float xAdvance;
- float yAdvance;
-
- public float XBearing {
+ double xBearing;
+ double yBearing;
+ double width;
+ double height;
+ double xAdvance;
+ double yAdvance;
+ public TextExtents (double xBearing, double yBearing, double width, double height, double xAdvance, double yAdvance) {
+ this.xBearing = xBearing;
+ this.yBearing = yBearing;
+ this.width = width;
+ this.height = height;
+ this.xAdvance = xAdvance;
+ this.yAdvance = yAdvance;
+ }
+ public double XBearing {
get => xBearing;
set { xBearing = value; }
}
- public float YBearing {
+ public double YBearing {
get => yBearing;
set { yBearing = value; }
}
- public float Width {
+ public double Width {
get => width;
set { width = value; }
}
- public float Height {
+ public double Height {
get => height;
set { height = value; }
}
- public float XAdvance {
+ public double XAdvance {
get => xAdvance;
set { xAdvance = value; }
}
- public float YAdvance {
+ public double YAdvance {
get => yAdvance;
set { yAdvance = value; }
}
using (Showcase app = new Showcase ()) {
app.WindowTitle = "C.R.O.W Showcase";
- app.SetWindowIcon ("#Crow.Icons.crow.png");
+ //app.SetWindowIcon ("#Crow.Icons.crow.png");
//app.Theme = @"C:\Users\Jean-Philippe\source\Crow\Themes\TestTheme";
CurrentProgramInstance = app;
//Interface.UPDATE_INTERVAL = 50;
if (bytes.Length < size)
bytes = size > 512 ? new byte[size] : stackalloc byte[size];
- int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes);
+ int encodedBytes = buff.ToUtf8 (bytes);
if (encodedBytes > 0) {
bytes[encodedBytes++] = 0;
if (bytes.Length < size)
bytes = size > 512 ? new byte[size] : stackalloc byte[size];
- int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes);
+ int encodedBytes = buff.ToUtf8 (bytes);
gr.SetSource (SelectionBackground);
gr.Rectangle (selRect);
using System.Diagnostics;
+using Drawing2D;
namespace Samples
{
//Tutorial
using Crow;
-
+using Drawing2D;
using Glfw;
namespace TestWidget {