diff --git a/Terminal.Gui/Drawing/LineCanvas.cs b/Terminal.Gui/Drawing/LineCanvas.cs index aa7691368..8261b156a 100644 --- a/Terminal.Gui/Drawing/LineCanvas.cs +++ b/Terminal.Gui/Drawing/LineCanvas.cs @@ -1,9 +1,24 @@ #nullable enable namespace Terminal.Gui; -/// Facilitates box drawing and line intersection detection and rendering. Does not support diagonal lines. +/// Facilitates box drawing and line intersection detection and rendering. Does not support diagonal lines. public class LineCanvas : IDisposable { + /// Creates a new instance. + public LineCanvas () + { + // TODO: Refactor ConfigurationManager to not use an event handler for this. + // Instead, have it call a method on any class appropriately attributed + // to update the cached values. See Issue #2871 + Applied += ConfigurationManager_Applied; + } + + private readonly List _lines = []; + + /// Creates a new instance with the given . + /// Initial lines for the canvas. + public LineCanvas (IEnumerable lines) : this () { _lines = lines.ToList (); } + /// /// Optional which when present overrides the /// (colors) of lines in the canvas. This can be used e.g. to apply a global @@ -11,7 +26,321 @@ public class LineCanvas : IDisposable /// public FillPair? Fill { get; set; } - private readonly List _lines = []; + private Rectangle _cachedBounds; + + /// + /// Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is + /// the furthest left/top and Size is defined by the line that extends the furthest right/bottom. + /// + public Rectangle Bounds + { + get + { + if (_cachedBounds.IsEmpty) + { + if (_lines.Count == 0) + { + return _cachedBounds; + } + + Rectangle bounds = _lines [0].Bounds; + + for (var i = 1; i < _lines.Count; i++) + { + bounds = Rectangle.Union (bounds, _lines [i].Bounds); + } + + if (bounds is { Width: 0 } or { Height: 0 }) + { + bounds = bounds with + { + Width = Math.Clamp (bounds.Width, 1, short.MaxValue), + Height = Math.Clamp (bounds.Height, 1, short.MaxValue) + }; + } + + _cachedBounds = bounds; + } + + return _cachedBounds; + } + } + + /// Gets the lines in the canvas. + public IReadOnlyCollection Lines => _lines.AsReadOnly (); + + /// + /// Adds a new long line to the canvas starting at . + /// + /// Use positive for the line to extend Right and negative for Left when + /// is . + /// + /// + /// Use positive for the line to extend Down and negative for Up when + /// is . + /// + /// + /// Starting point. + /// + /// The length of line. 0 for an intersection (cross or T). Positive for Down/Right. Negative for + /// Up/Left. + /// + /// The direction of the line. + /// The style of line to use + /// + public void AddLine ( + Point start, + int length, + Orientation orientation, + LineStyle style, + Attribute? attribute = null + ) + { + _cachedBounds = Rectangle.Empty; + _lines.Add (new (start, length, orientation, style, attribute)); + } + + /// Adds a new line to the canvas + /// + public void AddLine (StraightLine line) + { + _cachedBounds = Rectangle.Empty; + _lines.Add (line); + } + + private Region? _exclusionRegion; + + /// + /// Causes the provided region to be excluded from and . + /// + /// + /// + /// Each call to this method will add to the exclusion region. To clear the exclusion region, call + /// . + /// + /// + public void Exclude (Region region) + { + _exclusionRegion ??= new (); + _exclusionRegion.Union (region); + } + + /// + /// Clears the exclusion region. After calling this method, and will + /// return all points in the canvas. + /// + public void ClearExclusions () { _exclusionRegion = null; } + + /// Clears all lines from the LineCanvas. + public void Clear () + { + _cachedBounds = Rectangle.Empty; + _lines.Clear (); + ClearExclusions (); + } + + /// + /// Clears any cached states from the canvas. Call this method if you make changes to lines that have already been + /// added. + /// + public void ClearCache () { _cachedBounds = Rectangle.Empty; } + + /// + /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their + /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate + /// intersection symbols. + /// + /// + /// + /// Only the points within the of the canvas that are not in the exclusion region will be + /// returned. To exclude points from the map, use . + /// + /// + /// A map of all the points within the canvas. + public Dictionary GetCellMap () + { + Dictionary map = new (); + + // walk through each pixel of the bitmap + for (int y = Bounds.Y; y < Bounds.Y + Bounds.Height; y++) + { + for (int x = Bounds.X; x < Bounds.X + Bounds.Width; x++) + { + IntersectionDefinition? [] intersects = _lines + .Select (l => l.Intersects (x, y)) + .Where (i => i is { }) + .ToArray (); + + Cell? cell = GetCellForIntersects (Application.Driver, intersects); + + if (cell is { } && _exclusionRegion?.Contains (x, y) is null or false) + { + map.Add (new (x, y), cell); + } + } + } + + return map; + } + + // TODO: Unless there's an obvious use case for this API we should delete it in favor of the + // simpler version that doesn't take an area. + /// + /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their + /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate + /// intersection symbols. + /// + /// + /// + /// Only the points within the of the canvas that are not in the exclusion region will be + /// returned. To exclude points from the map, use . + /// + /// + /// A rectangle to constrain the search by. + /// A map of the points within the canvas that intersect with . + public Dictionary GetMap (Rectangle inArea) + { + Dictionary map = new (); + + // walk through each pixel of the bitmap + for (int y = inArea.Y; y < inArea.Y + inArea.Height; y++) + { + for (int x = inArea.X; x < inArea.X + inArea.Width; x++) + { + IntersectionDefinition? [] intersects = _lines + .Select (l => l.Intersects (x, y)) + .Where (i => i is { }) + .ToArray (); + + Rune? rune = GetRuneForIntersects (Application.Driver, intersects); + + if (rune is { } && _exclusionRegion?.Contains (x, y) is null or false) + { + map.Add (new (x, y), rune.Value); + } + } + } + + return map; + } + + /// + /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their + /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate + /// intersection symbols. + /// + /// + /// + /// Only the points within the of the canvas that are not in the exclusion region will be + /// returned. To exclude points from the map, use . + /// + /// + /// A map of all the points within the canvas. + public Dictionary GetMap () { return GetMap (Bounds); } + + /// Merges one line canvas into this one. + /// + public void Merge (LineCanvas lineCanvas) + { + foreach (StraightLine line in lineCanvas._lines) + { + AddLine (line); + } + + if (lineCanvas._exclusionRegion is { }) + { + _exclusionRegion ??= new (); + _exclusionRegion.Union (lineCanvas._exclusionRegion); + } + } + + /// Removes the last line added to the canvas + /// + public StraightLine RemoveLastLine () + { + StraightLine? l = _lines.LastOrDefault (); + + if (l is { }) + { + _lines.Remove (l); + } + + return l!; + } + + /// + /// Returns the contents of the line canvas rendered to a string. The string will include all columns and rows, + /// even if has negative coordinates. For example, if the canvas contains a single line that + /// starts at (-1,-1) with a length of 2, the rendered string will have a length of 2. + /// + /// The canvas rendered to a string. + public override string ToString () + { + if (Bounds.IsEmpty) + { + return string.Empty; + } + + // Generate the rune map for the entire canvas + Dictionary runeMap = GetMap (); + + // Create the rune canvas + Rune [,] canvas = new Rune [Bounds.Height, Bounds.Width]; + + // Copy the rune map to the canvas, adjusting for any negative coordinates + foreach (KeyValuePair kvp in runeMap) + { + int x = kvp.Key.X - Bounds.X; + int y = kvp.Key.Y - Bounds.Y; + canvas [y, x] = kvp.Value; + } + + // Convert the canvas to a string + var sb = new StringBuilder (); + + for (var y = 0; y < canvas.GetLength (0); y++) + { + for (var x = 0; x < canvas.GetLength (1); x++) + { + Rune r = canvas [y, x]; + sb.Append (r.Value == 0 ? ' ' : r.ToString ()); + } + + if (y < canvas.GetLength (0) - 1) + { + sb.AppendLine (); + } + } + + return sb.ToString (); + } + + private static bool All (IntersectionDefinition? [] intersects, Orientation orientation) + { + return intersects.All (i => i!.Line.Orientation == orientation); + } + + private void ConfigurationManager_Applied (object? sender, ConfigurationManagerEventArgs e) + { + foreach (KeyValuePair irr in _runeResolvers) + { + irr.Value.SetGlyphs (); + } + } + + /// + /// Returns true if all requested appear in and there are + /// no additional + /// + /// + /// + /// + private static bool Exactly (HashSet intersects, params IntersectionType [] types) { return intersects.SetEquals (types); } + + private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects) + { + return Fill?.GetAttribute (intersects [0]!.Point) ?? intersects [0]!.Line.Attribute; + } private readonly Dictionary _runeResolvers = new () { @@ -55,305 +384,6 @@ public class LineCanvas : IDisposable // TODO: Add other resolvers }; - private Rectangle _cachedViewport; - - /// Creates a new instance. - public LineCanvas () - { - // TODO: Refactor ConfigurationManager to not use an event handler for this. - // Instead, have it call a method on any class appropriately attributed - // to update the cached values. See Issue #2871 - Applied += ConfigurationManager_Applied; - } - - /// Creates a new instance with the given . - /// Initial lines for the canvas. - public LineCanvas (IEnumerable lines) : this () { _lines = lines.ToList (); } - - /// - /// Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is - /// furthest left/top and Size is defined by the line that extends the furthest right/bottom. - /// - public Rectangle Viewport - { - get - { - if (_cachedViewport.IsEmpty) - { - if (_lines.Count == 0) - { - return _cachedViewport; - } - - Rectangle viewport = _lines [0].Viewport; - - for (var i = 1; i < _lines.Count; i++) - { - viewport = Rectangle.Union (viewport, _lines [i].Viewport); - } - - if (viewport is { Width: 0 } or { Height: 0 }) - { - viewport = viewport with - { - Width = Math.Clamp (viewport.Width, 1, short.MaxValue), - Height = Math.Clamp (viewport.Height, 1, short.MaxValue) - }; - } - - _cachedViewport = viewport; - } - - return _cachedViewport; - } - } - - /// Gets the lines in the canvas. - public IReadOnlyCollection Lines => _lines.AsReadOnly (); - - /// - public void Dispose () { Applied -= ConfigurationManager_Applied; } - - /// - /// Adds a new long line to the canvas starting at . - /// - /// Use positive for the line to extend Right and negative for Left when - /// is . - /// - /// - /// Use positive for the line to extend Down and negative for Up when - /// is . - /// - /// - /// Starting point. - /// - /// The length of line. 0 for an intersection (cross or T). Positive for Down/Right. Negative for - /// Up/Left. - /// - /// The direction of the line. - /// The style of line to use - /// - public void AddLine ( - Point start, - int length, - Orientation orientation, - LineStyle style, - Attribute? attribute = null - ) - { - _cachedViewport = Rectangle.Empty; - _lines.Add (new (start, length, orientation, style, attribute)); - } - - /// Adds a new line to the canvas - /// - public void AddLine (StraightLine line) - { - _cachedViewport = Rectangle.Empty; - _lines.Add (line); - } - - /// Clears all lines from the LineCanvas. - public void Clear () - { - _cachedViewport = Rectangle.Empty; - _lines.Clear (); - _exclusionRegion = null; - } - - private Region? _exclusionRegion; - - /// - /// Gets the list of locations that will be excluded from and . - /// - public void Exclude (Region region) - { - _exclusionRegion ??= new Region (); - _exclusionRegion.Union (region); - } - - /// - /// Clears any cached states from the canvas Call this method if you make changes to lines that have already been - /// added. - /// - public void ClearCache () { _cachedViewport = Rectangle.Empty; } - - /// - /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their - /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate - /// intersection symbols. - /// - /// A map of all the points within the canvas. - public Dictionary GetCellMap () - { - Dictionary map = new (); - - // walk through each pixel of the bitmap - for (int y = Viewport.Y; y < Viewport.Y + Viewport.Height; y++) - { - for (int x = Viewport.X; x < Viewport.X + Viewport.Width; x++) - { - IntersectionDefinition? [] intersects = _lines - .Select (l => l.Intersects (x, y)) - .Where (i => i is { }) - .ToArray (); - - Cell? cell = GetCellForIntersects (Application.Driver, intersects); - - if (cell is { } && _exclusionRegion?.Contains (x, y) is null or false) - { - map.Add (new (x, y), cell); - } - } - } - - return map; - } - - // TODO: Unless there's an obvious use case for this API we should delete it in favor of the - // simpler version that doesn't take an area. - /// - /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their - /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate - /// intersection symbols. - /// - /// A rectangle to constrain the search by. - /// A map of the points within the canvas that intersect with . - public Dictionary GetMap (Rectangle inArea) - { - Dictionary map = new (); - - // walk through each pixel of the bitmap - for (int y = inArea.Y; y < inArea.Y + inArea.Height; y++) - { - for (int x = inArea.X; x < inArea.X + inArea.Width; x++) - { - IntersectionDefinition? [] intersects = _lines - .Select (l => l.Intersects (x, y)) - .Where (i => i is { }) - .ToArray (); - - Rune? rune = GetRuneForIntersects (Application.Driver, intersects); - - if (rune is { } && _exclusionRegion?.Contains (x, y) is null or false) - { - map.Add (new (x, y), rune.Value); - } - } - } - - return map; - } - - /// - /// Evaluates the lines that have been added to the canvas and returns a map containing the glyphs and their - /// locations. The glyphs are the characters that should be rendered so that all lines connect up with the appropriate - /// intersection symbols. - /// - /// A map of all the points within the canvas. - public Dictionary GetMap () { return GetMap (Viewport); } - - /// Merges one line canvas into this one. - /// - public void Merge (LineCanvas lineCanvas) - { - foreach (StraightLine line in lineCanvas._lines) - { - AddLine (line); - } - - if (lineCanvas._exclusionRegion is { }) - { - _exclusionRegion ??= new (); - _exclusionRegion.Union (lineCanvas._exclusionRegion); - } - } - - /// Removes the last line added to the canvas - /// - public StraightLine RemoveLastLine () - { - StraightLine? l = _lines.LastOrDefault (); - - if (l is { }) - { - _lines.Remove (l); - } - - return l!; - } - - /// - /// Returns the contents of the line canvas rendered to a string. The string will include all columns and rows, - /// even if has negative coordinates. For example, if the canvas contains a single line that - /// starts at (-1,-1) with a length of 2, the rendered string will have a length of 2. - /// - /// The canvas rendered to a string. - public override string ToString () - { - if (Viewport.IsEmpty) - { - return string.Empty; - } - - // Generate the rune map for the entire canvas - Dictionary runeMap = GetMap (); - - // Create the rune canvas - Rune [,] canvas = new Rune [Viewport.Height, Viewport.Width]; - - // Copy the rune map to the canvas, adjusting for any negative coordinates - foreach (KeyValuePair kvp in runeMap) - { - int x = kvp.Key.X - Viewport.X; - int y = kvp.Key.Y - Viewport.Y; - canvas [y, x] = kvp.Value; - } - - // Convert the canvas to a string - var sb = new StringBuilder (); - - for (var y = 0; y < canvas.GetLength (0); y++) - { - for (var x = 0; x < canvas.GetLength (1); x++) - { - Rune r = canvas [y, x]; - sb.Append (r.Value == 0 ? ' ' : r.ToString ()); - } - - if (y < canvas.GetLength (0) - 1) - { - sb.AppendLine (); - } - } - - return sb.ToString (); - } - - private bool All (IntersectionDefinition? [] intersects, Orientation orientation) { return intersects.All (i => i!.Line.Orientation == orientation); } - - private void ConfigurationManager_Applied (object? sender, ConfigurationManagerEventArgs e) - { - foreach (KeyValuePair irr in _runeResolvers) - { - irr.Value.SetGlyphs (); - } - } - - /// - /// Returns true if all requested appear in and there are - /// no additional - /// - /// - /// - /// - private bool Exactly (HashSet intersects, params IntersectionType [] types) { return intersects.SetEquals (types); } - - private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects) - { - return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) : intersects [0]!.Line.Attribute; - } - private Cell? GetCellForIntersects (ConsoleDriver? driver, IntersectionDefinition? [] intersects) { if (!intersects.Any ()) @@ -695,7 +725,7 @@ public class LineCanvas : IDisposable internal Rune _thickBoth; internal Rune _thickH; internal Rune _thickV; - public IntersectionRuneResolver () { SetGlyphs (); } + protected IntersectionRuneResolver () { SetGlyphs (); } public Rune? GetRuneForIntersects (ConsoleDriver? driver, IntersectionDefinition? [] intersects) { @@ -871,4 +901,11 @@ public class LineCanvas : IDisposable _normal = Glyphs.URCorner; } } + + /// + public void Dispose () + { + Applied -= ConfigurationManager_Applied; + GC.SuppressFinalize (this); + } } diff --git a/Terminal.Gui/Drawing/StraightLine.cs b/Terminal.Gui/Drawing/StraightLine.cs index fe2ccdc1d..c2b1e034b 100644 --- a/Terminal.Gui/Drawing/StraightLine.cs +++ b/Terminal.Gui/Drawing/StraightLine.cs @@ -6,11 +6,11 @@ public class StraightLine { /// Creates a new instance of the class. - /// - /// - /// - /// - /// + /// The start location. + /// The length of the line. + /// The orientation of the line. + /// The line style. + /// The attribute to be used for rendering the line. public StraightLine ( Point start, int length, @@ -43,11 +43,11 @@ public class StraightLine /// /// Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is - /// furthest left/top and Size is defined by the line that extends the furthest right/bottom. + /// the furthest left/top and Size is defined by the line that extends the furthest right/bottom. /// - // PERF: Probably better to store the rectangle rather than make a new one on every single access to Viewport. - internal Rectangle Viewport + // PERF: Probably better to store the rectangle rather than make a new one on every single access to Bounds. + internal Rectangle Bounds { get { diff --git a/Terminal.Gui/View/View.Drawing.cs b/Terminal.Gui/View/View.Drawing.cs index f08c1e424..06b793c50 100644 --- a/Terminal.Gui/View/View.Drawing.cs +++ b/Terminal.Gui/View/View.Drawing.cs @@ -543,7 +543,7 @@ public partial class View // Drawing APIs return; } - if (!SuperViewRendersLineCanvas && LineCanvas.Viewport != Rectangle.Empty) + if (!SuperViewRendersLineCanvas && LineCanvas.Bounds != Rectangle.Empty) { foreach (KeyValuePair p in LineCanvas.GetCellMap ()) { diff --git a/Terminal.sln.DotSettings b/Terminal.sln.DotSettings index 219c41cbe..835e9828b 100644 --- a/Terminal.sln.DotSettings +++ b/Terminal.sln.DotSettings @@ -381,6 +381,10 @@ False True True + LL + LR + UL + UR False <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> diff --git a/UnitTests/Drawing/LineCanvasTests.cs b/UnitTests/Drawing/LineCanvasTests.cs index 4c38374e3..a9b6f4743 100644 --- a/UnitTests/Drawing/LineCanvasTests.cs +++ b/UnitTests/Drawing/LineCanvasTests.cs @@ -377,7 +377,7 @@ public class LineCanvasTests (ITestOutputHelper _output) canvas.AddLine (new (x, y), length, Orientation.Horizontal, LineStyle.Single); canvas.AddLine (new (x, y), length, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), canvas.Viewport); + Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), canvas.Bounds); } [InlineData ( @@ -458,7 +458,7 @@ public class LineCanvasTests (ITestOutputHelper _output) var canvas = new LineCanvas (); canvas.AddLine (new (x, y), length, Orientation.Horizontal, LineStyle.Single); - Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), canvas.Viewport); + Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), canvas.Bounds); } [Fact] @@ -480,27 +480,27 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a short horiz line for ╔╡ lc.AddLine (new (x, y), 2, Orientation.Horizontal, LineStyle.Double); - Assert.Equal (new (x, y, 2, 1), lc.Viewport); + Assert.Equal (new (x, y, 2, 1), lc.Bounds); //LHS line down lc.AddLine (new (x, y), height, Orientation.Vertical, LineStyle.Double); - Assert.Equal (new (x, y, 2, 2), lc.Viewport); + Assert.Equal (new (x, y, 2, 2), lc.Bounds); //Vertical line before Title, results in a ╡ lc.AddLine (new (x + 1, y), 0, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (x, y, 2, 2), lc.Viewport); + Assert.Equal (new (x, y, 2, 2), lc.Bounds); //Vertical line after Title, results in a ╞ lc.AddLine (new (x + 2, y), 0, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (x, y, 3, 2), lc.Viewport); + Assert.Equal (new (x, y, 3, 2), lc.Bounds); // remainder of top line lc.AddLine (new (x + 2, y), width - 1, Orientation.Horizontal, LineStyle.Double); - Assert.Equal (new (x, y, 4, 2), lc.Viewport); + Assert.Equal (new (x, y, 4, 2), lc.Bounds); //RHS line down lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double); - Assert.Equal (new (x, y, 4, 2), lc.Viewport); + Assert.Equal (new (x, y, 4, 2), lc.Bounds); TestHelpers.AssertEqual ( _output, @@ -530,27 +530,27 @@ public class LineCanvasTests (ITestOutputHelper _output) // Add a short horiz line for ╔╡ lc.AddLine (new (x, y), 2, Orientation.Horizontal, LineStyle.Double); - Assert.Equal (new (x, y, 2, 1), lc.Viewport); + Assert.Equal (new (x, y, 2, 1), lc.Bounds); //LHS line down lc.AddLine (new (x, y), height, Orientation.Vertical, LineStyle.Double); - Assert.Equal (new (x, y, 2, 2), lc.Viewport); + Assert.Equal (new (x, y, 2, 2), lc.Bounds); //Vertical line before Title, results in a ╡ lc.AddLine (new (x + 1, y), 0, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (x, y, 2, 2), lc.Viewport); + Assert.Equal (new (x, y, 2, 2), lc.Bounds); //Vertical line after Title, results in a ╞ lc.AddLine (new (x + 2, y), 0, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (x, y, 3, 2), lc.Viewport); + Assert.Equal (new (x, y, 3, 2), lc.Bounds); // remainder of top line lc.AddLine (new (x + 2, y), width - 1, Orientation.Horizontal, LineStyle.Double); - Assert.Equal (new (x, y, 4, 2), lc.Viewport); + Assert.Equal (new (x, y, 4, 2), lc.Bounds); //RHS line down lc.AddLine (new (x + width, y), height, Orientation.Vertical, LineStyle.Double); - Assert.Equal (new (x, y, 4, 2), lc.Viewport); + Assert.Equal (new (x, y, 4, 2), lc.Bounds); TestHelpers.AssertEqual ( _output, @@ -567,13 +567,13 @@ public class LineCanvasTests (ITestOutputHelper _output) { var lc = new LineCanvas (); - Assert.Equal (Rectangle.Empty, lc.Viewport); + Assert.Equal (Rectangle.Empty, lc.Bounds); lc.AddLine (Point.Empty, 2, Orientation.Horizontal, LineStyle.Double); - Assert.NotEqual (Rectangle.Empty, lc.Viewport); + Assert.NotEqual (Rectangle.Empty, lc.Bounds); lc.Clear (); - Assert.Equal (Rectangle.Empty, lc.Viewport); + Assert.Equal (Rectangle.Empty, lc.Bounds); } [InlineData (0, 0, Orientation.Horizontal, "─")] @@ -872,7 +872,7 @@ public class LineCanvasTests (ITestOutputHelper _output) //// Left Up //canvas.AddLine (new Point (0, 3), -3, Orientation.Vertical, LineStyle.Single); - Assert.Equal (new (0, 0, 2, 2), canvas.Viewport); + Assert.Equal (new (0, 0, 2, 2), canvas.Bounds); Dictionary map = canvas.GetMap (); Assert.Equal (2, map.Count); diff --git a/UnitTests/Drawing/StraightLineTests.cs b/UnitTests/Drawing/StraightLineTests.cs index 4395ea0c1..39c67d81e 100644 --- a/UnitTests/Drawing/StraightLineTests.cs +++ b/UnitTests/Drawing/StraightLineTests.cs @@ -321,6 +321,6 @@ public class StraightLineTests (ITestOutputHelper output) { var sl = new StraightLine (new (x, y), length, orientation, LineStyle.Single); - Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), sl.Viewport); + Assert.Equal (new (expectedX, expectedY, expectedWidth, expectedHeight), sl.Bounds); } }