diff --git a/Dashboard.Drawing/DbBaseCommands.cs b/Dashboard.Drawing/DbBaseCommands.cs index 689616b..937640a 100644 --- a/Dashboard.Drawing/DbBaseCommands.cs +++ b/Dashboard.Drawing/DbBaseCommands.cs @@ -23,9 +23,9 @@ namespace Dashboard.Drawing { AddCommand(DrawPoint = new DrawCommand("Point", this, PointCommandArgs.CommandSize)); AddCommand(DrawLine = new DrawCommand("Line", this, LineCommandArgs.CommandSize)); - AddCommand(DrawRectF = new RectCommand(RectCommand.Mode.Fill)); - AddCommand(DrawRectS = new RectCommand(RectCommand.Mode.Strike)); - AddCommand(DrawRectFS = new RectCommand(RectCommand.Mode.FillStrike)); + AddCommand(DrawRectF = new RectCommand(this, RectCommand.Mode.Fill)); + AddCommand(DrawRectS = new RectCommand(this, RectCommand.Mode.Strike)); + AddCommand(DrawRectFS = new RectCommand(this, RectCommand.Mode.FillStrike)); } public static readonly DbBaseCommands Instance = new DbBaseCommands(); @@ -33,13 +33,15 @@ namespace Dashboard.Drawing public struct PointCommandArgs : IParameterSerializer { - public Vector3 Position { get; private set; } + public Vector2 Position { get; private set; } + public float Depth { get; private set; } public float Size { get; private set; } public IBrush? Brush { get; private set; } - public PointCommandArgs(Vector3 position, float size, IBrush brush) + public PointCommandArgs(Vector2 position, float depth, float size, IBrush brush) { Position = position; + Depth = depth; Brush = brush; Size = size; } @@ -51,7 +53,7 @@ namespace Dashboard.Drawing Span value = stackalloc Value[] { - new Value(Position, Size, queue.RequireResource(Brush!)) + new Value(Position, Depth, Size, queue.RequireResource(Brush!)) }; MemoryMarshal.AsBytes(value).CopyTo(bytes); @@ -67,28 +69,31 @@ namespace Dashboard.Drawing Value value = MemoryMarshal.AsRef(bytes); Position = value.Position; + Depth = value.Depth; Size = value.Size; Brush = (IBrush)queue.Resources[value.BrushIndex]; } - private record struct Value(Vector3 Position, float Size, int BrushIndex); + private record struct Value(Vector2 Position, float Depth, float Size, int BrushIndex); public static readonly int CommandSize = Unsafe.SizeOf(); } public struct LineCommandArgs : IParameterSerializer { - public Vector3 Start { get; private set; } - public Vector3 End { get; private set; } + public Vector2 Start { get; private set; } + public Vector2 End { get; private set; } + public float Depth { get; private set; } public float Size { get; private set; } public IBrush? Brush { get; private set; } - public LineCommandArgs(Vector3 start, Vector3 end, float size, IBrush brush) + public LineCommandArgs(Vector2 start, Vector2 end, float depth, float size, IBrush brush) { Start = start; End = end; - Brush = brush; + Depth = depth; Size = size; + Brush = brush; } public int Serialize(DrawQueue queue, Span bytes) @@ -98,7 +103,7 @@ namespace Dashboard.Drawing Span value = stackalloc Value[] { - new Value(Start, End, Size, queue.RequireResource(Brush!)) + new Value(Start, End, Depth, Size, queue.RequireResource(Brush!)) }; MemoryMarshal.AsBytes(value).CopyTo(bytes); @@ -114,21 +119,17 @@ namespace Dashboard.Drawing Start = value.Start; End = value.End; + Depth = value.Depth; Size = value.Size; Brush = (IBrush)queue.Resources[value.BrushIndex]; } - private record struct Value(Vector3 Start, Vector3 End, float Size, int BrushIndex); + private record struct Value(Vector2 Start, Vector2 End, float Depth, float Size, int BrushIndex); public static readonly int CommandSize = Unsafe.SizeOf(); } - public enum BorderKind - { - Inset = -1, - Center = 0, - Outset = 1, - } + public class RectCommand : IDrawCommand { @@ -137,9 +138,9 @@ namespace Dashboard.Drawing public IDrawExtension Extension { get; } public int Length { get; } - public RectCommand(Mode mode) + public RectCommand(IDrawExtension extension, Mode mode) { - Extension = DbBaseCommands.Instance; + Extension = extension; _mode = mode; switch (mode) @@ -175,15 +176,15 @@ namespace Dashboard.Drawing { case Mode.Fill: ref readonly RectF f = ref MemoryMarshal.AsRef(param); - args = new RectCommandArgs(f.Start, f.End, (IBrush)queue.Resources[f.FillBrushIndex]); + args = new RectCommandArgs(f.Start, f.End, f.Depth, (IBrush)queue.Resources[f.FillBrushIndex]); break; case Mode.Strike: ref readonly RectS s = ref MemoryMarshal.AsRef(param); - args = new RectCommandArgs(s.Start, s.End, (IBrush)queue.Resources[s.StrikeBrushIndex], s.StrikeSize, s.BorderKind); + args = new RectCommandArgs(s.Start, s.End, s.Depth, (IBrush)queue.Resources[s.StrikeBrushIndex], s.StrikeSize, s.BorderKind); break; default: ref readonly RectFS fs = ref MemoryMarshal.AsRef(param); - args = new RectCommandArgs(fs.Start, fs.End, (IBrush)queue.Resources[fs.FillBrushIndex], + args = new RectCommandArgs(fs.Start, fs.End, fs.Depth, (IBrush)queue.Resources[fs.FillBrushIndex], (IBrush)queue.Resources[fs.StrikeBrushIndex], fs.StrikeSize, fs.BorderKind); break; } @@ -207,12 +208,14 @@ namespace Dashboard.Drawing ref RectF f = ref MemoryMarshal.AsRef(param); f.Start = obj.Start; f.End = obj.End; + f.Depth = obj.Depth; f.FillBrushIndex = queue.RequireResource(obj.FillBrush!); break; case Mode.Strike: ref RectS s = ref MemoryMarshal.AsRef(param); s.Start = obj.Start; s.End = obj.End; + s.Depth = obj.Depth; s.StrikeBrushIndex = queue.RequireResource(obj.StrikeBrush!); s.StrikeSize = obj.StrikeSize; s.BorderKind = obj.BorderKind; @@ -221,6 +224,7 @@ namespace Dashboard.Drawing ref RectFS fs = ref MemoryMarshal.AsRef(param); fs.Start = obj.Start; fs.End = obj.End; + fs.Depth = obj.Depth; fs.FillBrushIndex = queue.RequireResource(obj.FillBrush!); fs.StrikeBrushIndex = queue.RequireResource(obj.StrikeBrush!); fs.StrikeSize = obj.StrikeSize; @@ -239,42 +243,46 @@ namespace Dashboard.Drawing FillStrike = Fill | Strike, } - private record struct RectF(Vector3 Start, Vector3 End, int FillBrushIndex); - private record struct RectS(Vector3 Start, Vector3 End, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind); - private record struct RectFS(Vector3 Start, Vector3 End, int FillBrushIndex, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind); + private record struct RectF(Vector2 Start, Vector2 End, float Depth, int FillBrushIndex); + private record struct RectS(Vector2 Start, Vector2 End, float Depth, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind); + private record struct RectFS(Vector2 Start, Vector2 End, float Depth, int FillBrushIndex, int StrikeBrushIndex, float StrikeSize, BorderKind BorderKind); } public struct RectCommandArgs { - public Vector3 Start { get; private set; } - public Vector3 End { get; private set; } - public BorderKind BorderKind { get; private set; } = BorderKind.Center; + public Vector2 Start { get; private set; } + public Vector2 End { get; private set; } + public float Depth { get; private set; } public float StrikeSize { get; private set; } = 0f; + public BorderKind BorderKind { get; private set; } = BorderKind.Center; public IBrush? FillBrush { get; private set; } = null; public IBrush? StrikeBrush { get; private set; } = null; public bool IsStruck => StrikeSize != 0; - public RectCommandArgs(Vector3 start, Vector3 end, IBrush fillBrush) + public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush fillBrush) { Start = start; End = end; + Depth = depth; FillBrush = fillBrush; } - public RectCommandArgs(Vector3 start, Vector3 end, IBrush strikeBrush, float strikeSize, BorderKind borderKind) + public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush strikeBrush, float strikeSize, BorderKind borderKind) { Start = start; End = end; + Depth = depth; StrikeBrush = strikeBrush; StrikeSize = strikeSize; BorderKind = borderKind; } - public RectCommandArgs(Vector3 start, Vector3 end, IBrush fillBrush, IBrush strikeBrush, float strikeSize, + public RectCommandArgs(Vector2 start, Vector2 end, float depth, IBrush fillBrush, IBrush strikeBrush, float strikeSize, BorderKind borderKind) { Start = start; End = end; + Depth = depth; FillBrush = fillBrush; StrikeBrush = strikeBrush; StrikeSize = strikeSize; diff --git a/Dashboard.Drawing/DrawExtension.cs b/Dashboard.Drawing/DrawExtension.cs index 12e1da4..f95fbfd 100644 --- a/Dashboard.Drawing/DrawExtension.cs +++ b/Dashboard.Drawing/DrawExtension.cs @@ -1,7 +1,9 @@ using System.Collections.Generic; using System.Collections.Immutable; +using System.Drawing; using System.Linq; using System.Numerics; +using System.Runtime.InteropServices; namespace Dashboard.Drawing { @@ -62,62 +64,62 @@ namespace Dashboard.Drawing return queue.GetController(extension); } - public static void Point(this DrawQueue queue, Vector3 position, float size, IBrush brush) + public static void Point(this DrawQueue queue, Vector2 position, float depth, float size, IBrush brush) { - Vector3 radius = new Vector3(size / 2f); - Box3d bounds = new Box3d(position - radius, position + radius); + Vector2 radius = new Vector2(0.5f * size); + Box2d bounds = new Box2d(position - radius, position + radius); IDrawController controller = queue.GetController(DbBaseCommands.Instance); - controller.EnsureBounds(bounds); - controller.Write(DbBaseCommands.Instance.DrawPoint, new PointCommandArgs(position, size, brush)); + controller.EnsureBounds(bounds, depth); + controller.Write(DbBaseCommands.Instance.DrawPoint, new PointCommandArgs(position, depth, size, brush)); } - public static void Line(this DrawQueue queue, Vector3 start, Vector3 end, float size, IBrush brush) + public static void Line(this DrawQueue queue, Vector2 start, Vector2 end, float depth, float size, IBrush brush) { - Vector3 radius = new Vector3(size / 2f); - Vector3 min = Vector3.Min(start, end) - radius; - Vector3 max = Vector3.Max(start, end) + radius; - Box3d bounds = new Box3d(min, max); + Vector2 radius = new Vector2(size / 2f); + Vector2 min = Vector2.Min(start, end) - radius; + Vector2 max = Vector2.Max(start, end) + radius; + Box2d bounds = new Box2d(min, max); IDrawController controller = queue.GetController(DbBaseCommands.Instance); - controller.EnsureBounds(bounds); - controller.Write(DbBaseCommands.Instance.DrawLine, new LineCommandArgs(start, end, size, brush)); + controller.EnsureBounds(bounds, depth); + controller.Write(DbBaseCommands.Instance.DrawLine, new LineCommandArgs(start, end, depth, size, brush)); } - public static void Rect(this DrawQueue queue, Vector3 start, Vector3 end, IBrush fillBrush) + public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush fillBrush) { IDrawController controller = queue.GetController(DbBaseCommands.Instance); - Vector3 min = Vector3.Min(start, end); - Vector3 max = Vector3.Max(start, end); - controller.EnsureBounds(new Box3d(min, max)); - controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, fillBrush)); + Vector2 min = Vector2.Min(start, end); + Vector2 max = Vector2.Max(start, end); + controller.EnsureBounds(new Box2d(min, max), depth); + controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, depth, fillBrush)); } - public static void Rect(this DrawQueue queue, Vector3 start, Vector3 end, IBrush strikeBrush, float strikeSize, + public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush strikeBrush, float strikeSize, BorderKind kind = BorderKind.Center) { IDrawController controller = queue.GetController(DbBaseCommands.Instance); - Vector3 min = Vector3.Min(start, end); - Vector3 max = Vector3.Max(start, end); - controller.EnsureBounds(new Box3d(min, max)); - controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, strikeBrush, strikeSize, kind)); + Vector2 min = Vector2.Min(start, end); + Vector2 max = Vector2.Max(start, end); + controller.EnsureBounds(new Box2d(min, max), depth); + controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, depth, strikeBrush, strikeSize, kind)); } - public static void Rect(this DrawQueue queue, Vector3 start, Vector3 end, IBrush fillBrush, IBrush strikeBrush, + public static void Rect(this DrawQueue queue, Vector2 start, Vector2 end, float depth, IBrush fillBrush, IBrush strikeBrush, float strikeSize, BorderKind kind = BorderKind.Center) { IDrawController controller = queue.GetController(DbBaseCommands.Instance); - Vector3 min = Vector3.Min(start, end); - Vector3 max = Vector3.Max(start, end); - controller.EnsureBounds(new Box3d(min, max)); - controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, fillBrush, strikeBrush, strikeSize, kind)); + Vector2 min = Vector2.Min(start, end); + Vector2 max = Vector2.Max(start, end); + controller.EnsureBounds(new Box2d(min, max), depth); + controller.Write(DbBaseCommands.Instance.DrawRectF, new RectCommandArgs(start, end, depth, fillBrush, strikeBrush, strikeSize, kind)); } public static void Text(this DrawQueue queue, Vector3 position, IBrush brush, string text, IFont font, Anchor anchor = Anchor.Left) { IDrawController controller = queue.GetController(DbBaseCommands.Instance); - controller.EnsureBounds(new Box3d(position, position)); + controller.EnsureBounds(new Box2d(position.X, position.Y, position.X, position.Y), position.Z); controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, brush, anchor, position, text)); } @@ -125,7 +127,7 @@ namespace Dashboard.Drawing float borderRadius, string text, IFont font, Anchor anchor = Anchor.Left, BorderKind borderKind = BorderKind.Outset) { IDrawController controller = queue.GetController(DbBaseCommands.Instance); - controller.EnsureBounds(new Box3d(position, position)); + controller.EnsureBounds(new Box2d(position.X, position.Y, position.X, position.Y), position.Z); controller.Write(TextExtension.Instance.TextCommand, new TextCommandArgs(font, textBrush, anchor, position, text) { BorderBrush = borderBrush, diff --git a/Dashboard.Drawing/DrawQueue.cs b/Dashboard.Drawing/DrawQueue.cs index 6df93e2..82f9bba 100644 --- a/Dashboard.Drawing/DrawQueue.cs +++ b/Dashboard.Drawing/DrawQueue.cs @@ -178,9 +178,9 @@ namespace Dashboard.Drawing private class DrawController(DrawQueue Queue) : IDrawController { - public void EnsureBounds(Box3d bounds) + public void EnsureBounds(Box2d bounds, float depth) { - Queue.Bounds = Box3d.Union(Queue.Bounds, bounds); + Queue.Bounds = Box3d.Union(Queue.Bounds, bounds, depth); } public void Write(IDrawCommand command) @@ -239,11 +239,12 @@ namespace Dashboard.Drawing public bool MoveNext() { + if (_index == -1) + _index = 0; + if (_index >= _length) return false; - if (_index == -1) - _index = 0; _index += FromVlq(_stream[_index .. (_index + 5)], out int command); _current = _queue.Command[command]; @@ -336,7 +337,7 @@ namespace Dashboard.Drawing /// Ensures that the canvas is at least a certain size. /// /// The bounding box. - void EnsureBounds(Box3d bounds); + void EnsureBounds(Box2d bounds, float depth); /// /// Write into the command stream.