/// <summary> /// Creates a new rectangle shaped sub-path. /// </summary> public static void Rect(this Nvg nvg, Rectangle <float> rect) { InstructionQueue queue = nvg.instructionQueue; queue.AddMoveTo(rect.Origin); queue.AddLineTo(new(rect.Origin.X, rect.Max.Y)); queue.AddLineTo(rect.Max); queue.AddLineTo(new(rect.Max.X, rect.Origin.Y)); queue.AddClose(); }
/// <summary> /// Creates a new rounded rectangle shaped sub-path with varying radii for each corner. /// </summary> public static void RoundedRectVarying(this Nvg nvg, Rectangle <float> rect, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft) { if (radTopLeft < 0.1f && radTopRight < 0.1f && radBottomRight < 0.1f && radBottomLeft < 0.1f) { Rect(nvg, rect); } else { InstructionQueue queue = nvg.instructionQueue; float factor = 1 - KAPPA90; Vector2D <float> half = Vector2D.Abs(rect.Size) * 0.5f; Vector2D <float> rBL = new(MathF.Min(radBottomLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomLeft, half.Y) * Maths.Sign(rect.Size.Y)); Vector2D <float> rBR = new(MathF.Min(radBottomRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomRight, half.Y) * Maths.Sign(rect.Size.Y)); Vector2D <float> rTR = new(MathF.Min(radTopRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopRight, half.Y) * Maths.Sign(rect.Size.Y)); Vector2D <float> rTL = new(MathF.Min(radTopLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopLeft, half.Y) * Maths.Sign(rect.Size.Y)); queue.AddMoveTo(new(rect.Origin.X, rect.Origin.Y + rTL.Y)); queue.AddLineTo(new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y)); queue.AddBezierTo( new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y * factor), new(rect.Origin.X + rBL.X * factor, rect.Origin.Y + rect.Size.Y), new(rect.Origin.X + rBL.X, rect.Origin.Y + rect.Size.Y) ); queue.AddLineTo(new(rect.Origin.X + rect.Size.X - rBR.X, rect.Origin.Y + rect.Size.Y)); queue.AddBezierTo( new(rect.Origin.X + rect.Size.X - rBR.X * factor, rect.Origin.Y + rect.Size.Y), new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y * factor), new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y) ); queue.AddLineTo(new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y)); queue.AddBezierTo( new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y * factor), new(rect.Origin.X + rect.Size.X - rTR.X * factor, rect.Origin.Y), new(rect.Origin.X + rect.Size.X - rTR.X, rect.Origin.Y) ); queue.AddLineTo(new(rect.Origin.X + rTL.X, rect.Origin.Y)); queue.AddBezierTo( new(rect.Origin.X + rTL.X * factor, rect.Origin.Y), new(rect.Origin.X, rect.Origin.Y + rTL.Y * factor), new(rect.Origin.X, rect.Origin.Y + rTL.Y) ); queue.AddClose(); } }
/// <summary> /// Creates a new ellipse shaped sub-path. /// </summary> public static void Ellipse(this Nvg nvg, Vector2D <float> c, float rx, float ry) { InstructionQueue queue = nvg.instructionQueue; queue.AddMoveTo(new(c.X - rx, c.Y)); queue.AddBezierTo( new(c.X - rx, c.Y + ry * KAPPA90), new(c.X - rx * KAPPA90, c.Y + ry), new(c.X, c.Y + ry)); queue.AddBezierTo( new(c.X + rx * KAPPA90, c.Y + ry), new(c.X + rx, c.Y + ry * KAPPA90), new(c.X + rx, c.Y)); queue.AddBezierTo( new(c.X + rx, c.Y - ry * KAPPA90), new(c.X + rx * KAPPA90, c.Y - ry), new(c.X, c.Y - ry)); queue.AddBezierTo( new(c.X - rx * KAPPA90, c.Y - ry), new(c.X - rx, c.Y - ry * KAPPA90), new(c.X - rx, c.Y)); queue.AddClose(); }