/// <summary> /// Draws a solid box with the specified dimensions to the buffer. /// </summary> /// <param name="x">The X coordinate of the box.</param> /// <param name="y">The Y coordinate of the box.</param> /// <param name="w">The width of the box.</param> /// <param name="h">The height of the box.</param> /// <param name="brush">The brush to draw the box with.</param> public void DrawBox(int x, int y, int w, int h, BufferBrush brush) { if (w < 0) { w *= -1; x -= w; } if (h < 0) { h *= -1; y -= h; } var b = _buffer; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { if (InBounds(x + i, y + j)) { b[y + j, x + i].BackColor = brush.GetColor(x + i, y + j); } } } }
/// <summary> /// Fills the entire buffer with a brush. /// </summary> /// <param name="brush">The brush to fill the buffer with.</param> public unsafe void ClearBrush(BufferBrush brush) { for (int i = _width - 1; i >= 0; i--) { for (int j = _height - 1; j >= 0; j--) { _buffer[j, i].ForeColor = brush.GetColor(i, j); _buffer[j, i].BackColor = brush.GetColor(i, j); _buffer[j, i].CharData = '\0'; } } }
/// <summary> /// Draws text to a buffer using the specified settings. /// </summary> /// <param name="buffer">The buffer to draw to.</param> /// <param name="text">The text to draw.</param> /// <param name="position">The position of the text.</param> /// <param name="brush">The brush to draw the text with.</param> /// <param name="alignment">The alignment of the text relative to its position.</param> public void Draw(ConsoleBuffer buffer, string text, Point position, BufferBrush brush, Alignment alignment) { int // Character offsets mx = 0, my = 0; Point p = new Point(); Point pc = new Point(); foreach (char c in text) { p.X = alignment == Alignment.Left ? mx : -CharWidth - mx; p.Y = my; p = p + position; if (c == '\n') { mx = 0; my += CharHeight + 1; } else if (!Char.IsControl(c)) { for (int i = 0; i < glyphs[c].Length; i++) { if (c > glyphs.Length) { continue; } if (glyphs[c] == null) { continue; } pc.Y = i; for (int j = 0; j < glyphs[c][i].Length; j++) { if (glyphs[c][i] == null) { continue; } if (!glyphs[c][i][j]) { continue; } pc.X = j; buffer.SetUnitBackColor(p + pc, brush.GetColor(p.X + pc.X, p.Y + pc.Y)); } } mx += CharWidth + 1; } } }
/// <summary> /// Draws a solid circle to the buffer with the specified attributes. /// </summary> /// <param name="x">The X position of the circle, relative to its center.</param> /// <param name="y">The Y position of the circle, relative to its center.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="brush">The brush to draw the circle with.</param> public void DrawCircle(int x, int y, int radius, BufferBrush brush) { if (radius < 0) { radius *= -1; } int rr = radius * radius; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { if (i * i + j * j <= rr && InBounds(x + i, y + j)) { _buffer[y + j, x + i].BackColor = brush.GetColor(x + i, y + j); } } } }
/// <summary> /// Draws a circle with the specified radius, border thickness, and attributes for both border and fill. /// </summary> /// <param name="x">The X position of the circle, relative to its center.</param> /// <param name="y">The Y position of the circle, relative to its center.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="thickness">The border thickness of the circle.</param> /// <param name="border">The border brush for the circle.</param> /// <param name="fill">The fill brush for the circle.</param> public void DrawCircle(int x, int y, int radius, int thickness, BufferBrush border, BufferBrush fill) { if (radius < 0) { radius *= -1; } if (thickness < 0) { thickness *= -1; } if (thickness > radius) { thickness = radius; } int rra = radius * radius; int rrb = (radius - thickness) * (radius - thickness); int d = 0; for (int i = -radius; i <= radius; i++) { for (int j = -radius; j <= radius; j++) { d = i * i + j * j; if (InBounds(x + i, y + j)) { if (d < rrb) { _buffer[y + j, x + i].BackColor = fill.GetColor(x + i, y + j); } else if (d <= rra) { _buffer[y + j, x + i].BackColor = border.GetColor(x + i, y + j); } } } } }
/// <summary> /// Draws a box with the specified border and fill brushes. /// </summary> /// <param name="x">The X position of the box.</param> /// <param name="y">The Y position of the box.</param> /// <param name="w">The width of the box.</param> /// <param name="h">The height of the box.</param> /// <param name="thickness">The border thickness of the box.</param> /// <param name="border">The brush to draw the border with.</param> /// <param name="fill">The brush to draw the fill with.</param> public void DrawBox(int x, int y, int w, int h, int thickness, BufferBrush border, BufferBrush fill) { if (w < 0) { w *= -1; x -= w; } if (h < 0) { h *= -1; y -= h; } if (thickness < 0) { thickness *= -1; } var b = _buffer; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { if (InBounds(x + i, y + j)) { if ((i >= thickness && i < w - thickness) && (j >= thickness && j < h - thickness)) { b[y + j, x + i].BackColor = fill.GetColor(x + i, y + j); } else { b[y + j, x + i].BackColor = border.GetColor(x + i, y + j); } } } } }
/// <summary> /// Draws a triangle with the specified border and fill brushes. /// </summary> /// <param name="triangle">The triangle to draw.</param> /// <param name="border">The border brush.</param> /// <param name="fill">The fill brush.</param> public void DrawTriangle(Triangle triangle, BufferBrush border, BufferBrush fill) { var bounds = triangle.GetBounds(); double area = triangle.Area; Point p = new Point(); double sum = 0; for (int i = bounds.Left; i < bounds.Right; i++) { for (int j = bounds.Top; j < bounds.Bottom; j++) { p.X = i; p.Y = j; sum = Triangle.GetArea(p, triangle.A, triangle.B) + Triangle.GetArea(p, triangle.B, triangle.C) + Triangle.GetArea(p, triangle.C, triangle.A); if (sum >= area - 1 && sum <= area + 1) { _buffer[j, i].BackColor = fill.GetColor(i, j); } } } DrawTriangle(triangle, border); }
/// <summary> /// Draws a circle with the specified radius, border thickness, and attributes for both border and fill. /// </summary> /// <param name="x">The X position of the circle, relative to its center.</param> /// <param name="y">The Y position of the circle, relative to its center.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="thickness">The border thickness of the circle.</param> /// <param name="border">The border brush for the circle.</param> /// <param name="fill">The fill brush for the circle.</param> public void DrawCircle(int x, int y, int radius, int thickness, BufferBrush border, BufferBrush fill) { if (radius < 0) radius *= -1; if (thickness < 0) thickness *= -1; if (thickness > radius) thickness = radius; int rra = radius * radius; int rrb = (radius - thickness) * (radius - thickness); int d = 0; for (int i = -radius; i <= radius; i++) for (int j = -radius; j <= radius; j++) { d = i * i + j * j; if (InBounds(x + i, y + j)) { if (d < rrb) { _buffer[y + j, x + i].BackColor = fill.GetColor(x + i, y + j); } else if (d <= rra) { _buffer[y + j, x + i].BackColor = border.GetColor(x + i, y + j); } } } }
/// <summary> /// Draws a solid circle to the buffer with the specified attributes. /// </summary> /// <param name="x">The X position of the circle, relative to its center.</param> /// <param name="y">The Y position of the circle, relative to its center.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="brush">The brush to draw the circle with.</param> public void DrawCircle(int x, int y, int radius, BufferBrush brush) { if (radius < 0) radius *= -1; int rr = radius * radius; for (int i = -radius; i <= radius; i++) for (int j = -radius; j <= radius; j++) { if (i * i + j * j <= rr && InBounds(x + i, y + j)) { _buffer[y + j, x + i].BackColor = brush.GetColor(x + i,y + j); } } }
/// <summary> /// Draws a box from the specified rectangle and brush information. /// </summary> /// <param name="rectangle">The bounds of the box to draw.</param> /// <param name="thickness">The border thickness of the box.</param> /// <param name="border">the border brush of the box.</param> /// <param name="fill">The fill brush of the box.</param> public void DrawBox(ref Rectangle rectangle, int thickness, BufferBrush border, BufferBrush fill) { DrawBox(rectangle.Top, rectangle.Left, rectangle.Width, rectangle.Height, thickness, border, fill); }
/// <summary> /// Draws a box with the specified border and fill brushes. /// </summary> /// <param name="x">The X position of the box.</param> /// <param name="y">The Y position of the box.</param> /// <param name="w">The width of the box.</param> /// <param name="h">The height of the box.</param> /// <param name="thickness">The border thickness of the box.</param> /// <param name="border">The brush to draw the border with.</param> /// <param name="fill">The brush to draw the fill with.</param> public void DrawBox(int x, int y, int w, int h, int thickness, BufferBrush border, BufferBrush fill) { if (w < 0) { w *= -1; x -= w; } if (h < 0) { h *= -1; y -= h; } if (thickness < 0) { thickness *= -1; } var b = _buffer; for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) { if (InBounds(x + i, y + j)) { if ((i >= thickness && i < w - thickness) && (j >= thickness && j < h - thickness)) { b[y + j, x + i].BackColor = fill.GetColor(x + i, y + j); } else { b[y + j, x + i].BackColor = border.GetColor(x + i, y + j); } } } }
/// <summary> /// Draws a solid box with the specified dimensions to the buffer. /// </summary> /// <param name="x">The X coordinate of the box.</param> /// <param name="y">The Y coordinate of the box.</param> /// <param name="w">The width of the box.</param> /// <param name="h">The height of the box.</param> /// <param name="brush">The brush to draw the box with.</param> public void DrawBox(int x, int y, int w, int h, BufferBrush brush) { if (w < 0) { w *= -1; x -= w; } if (h < 0) { h *= -1; y -= h; } var b = _buffer; for (int i = 0; i < w; i++) for (int j = 0; j < h; j++) { if (InBounds(x + i, y + j)) { b[y + j, x + i].BackColor = brush.GetColor(x + i, y + j); } } }
/// <summary> /// Draws a triangle to the buffer. /// </summary> /// <param name="triangle">The triangle to draw.</param> /// <param name="brush">The brush to draw the triangle with.</param> public void DrawTriangle(Triangle triangle, BufferBrush brush) { DrawLine(ref triangle.A, ref triangle.B, brush); DrawLine(ref triangle.B, ref triangle.C, brush); DrawLine(ref triangle.C, ref triangle.A, brush); }
/// <summary> /// Draws a triangle to the buffer. /// </summary> /// <param name="a">The first point of the triangle.</param> /// <param name="b">The second point of the triangle.</param> /// <param name="c">The third point of the triangle.</param> /// <param name="brush">The brush of the line.</param> public void DrawTriangle(ref Point a, ref Point b, ref Point c, BufferBrush brush) { DrawLine(ref a, ref b, brush); DrawLine(ref b, ref c, brush); DrawLine(ref c, ref a, brush); }
/// <summary> /// Draws a line to the buffer with the specified brush. /// </summary> /// <param name="a">The starting point of the line.</param> /// <param name="b">The ending point of the line.</param> /// <param name="brush">The brush to draw the line with.</param> public void DrawLine(ref Point a, ref Point b, BufferBrush brush) { DrawLine(a.X, a.Y, b.X, b.Y, brush); }
/// <summary> /// Flood fills a closed region containing the specified coordinates with a brush. /// </summary> /// <param name="x">The X coordinate to begin filling at.</param> /// <param name="y">The Y coordinate to begin filling at.</param> /// <param name="brush">The brush to fill the region with.</param> public void FloodFill(int x, int y, BufferBrush brush) { if (!InBounds(x, y)) { return; } var initColor = _buffer[y, x].BackColor; if (brush.GetColor(x, y) == initColor) { return; } List <Point> queue = new List <Point>(32); queue.Add(new Point(x, y)); Point p; int w, e, j; for (int i = 0; i < queue.Count; i++) { p = queue[i]; w = e = p.X; while (w - 1 >= 0) { if (_buffer[p.Y, w - 1].BackColor == initColor) { w--; } else { break; } } while (e + 1 < _width) { if (_buffer[p.Y, e + 1].BackColor == initColor) { e++; } else { break; } } for (j = w; j <= e; j++) { _buffer[p.Y, j].BackColor = brush.GetColor(j, p.Y); if (p.Y + 1 < _height) { if (_buffer[p.Y + 1, j].BackColor == initColor) { queue.Add(new Point(j, p.Y + 1)); } } if (p.Y - 1 >= 0) { if (_buffer[p.Y - 1, j].BackColor == initColor) { queue.Add(new Point(j, p.Y - 1)); } } } } }
/// <summary> /// Draws a line to the buffer. /// </summary> /// <param name="x">The starting X coordinate of the line.</param> /// <param name="y">The starting Y coordinate of the line.</param> /// <param name="x2">The ending X coordinate of the line.</param> /// <param name="y2">The ending Y coordinate of the line.</param> /// <param name="brush">The brush to draw the line with.</param> public void DrawLine(int x, int y, int x2, int y2, BufferBrush brush) { var b = _buffer; int w = x2 - x; int h = y2 - y; int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; if (w < 0) dx1 = -1; else if (w > 0) dx1 = 1; if (h < 0) dy1 = -1; else if (h > 0) dy1 = 1; if (w < 0) dx2 = -1; else if (w > 0) dx2 = 1; int longest = Math.Abs(w); int shortest = Math.Abs(h); if (!(longest > shortest)) { longest = Math.Abs(h); shortest = Math.Abs(w); if (h < 0) dy2 = -1; else if (h > 0) dy2 = 1; dx2 = 0; } int numerator = longest >> 1; for (int i = 0; i <= longest; i++) { if (InBounds(ref x, ref y)) { b[y, x].BackColor = brush.GetColor(x, y); } numerator += shortest; if (!(numerator < longest)) { numerator -= longest; x += dx1; y += dy1; } else { x += dx2; y += dy2; } } }
/// <summary> /// Draws a line to the buffer. /// </summary> /// <param name="x">The starting X coordinate of the line.</param> /// <param name="y">The starting Y coordinate of the line.</param> /// <param name="x2">The ending X coordinate of the line.</param> /// <param name="y2">The ending Y coordinate of the line.</param> /// <param name="brush">The brush to draw the line with.</param> public void DrawLine(int x, int y, int x2, int y2, BufferBrush brush) { var b = _buffer; int w = x2 - x; int h = y2 - y; int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0; if (w < 0) { dx1 = -1; } else if (w > 0) { dx1 = 1; } if (h < 0) { dy1 = -1; } else if (h > 0) { dy1 = 1; } if (w < 0) { dx2 = -1; } else if (w > 0) { dx2 = 1; } int longest = Math.Abs(w); int shortest = Math.Abs(h); if (!(longest > shortest)) { longest = Math.Abs(h); shortest = Math.Abs(w); if (h < 0) { dy2 = -1; } else if (h > 0) { dy2 = 1; } dx2 = 0; } int numerator = longest >> 1; for (int i = 0; i <= longest; i++) { if (InBounds(ref x, ref y)) { b[y, x].BackColor = brush.GetColor(x, y); } numerator += shortest; if (!(numerator < longest)) { numerator -= longest; x += dx1; y += dy1; } else { x += dx2; y += dy2; } } }
/// <summary> /// Draws a triangle with the specified border and fill brushes. /// </summary> /// <param name="triangle">The triangle to draw.</param> /// <param name="border">The border brush.</param> /// <param name="fill">The fill brush.</param> public void DrawTriangle(Triangle triangle, BufferBrush border, BufferBrush fill) { var bounds = triangle.GetBounds(); double area = triangle.Area; Point p = new Point(); double sum = 0; for (int i = bounds.Left; i < bounds.Right; i++) for (int j = bounds.Top; j < bounds.Bottom; j++) { p.X = i; p.Y = j; sum = Triangle.GetArea(p, triangle.A, triangle.B) + Triangle.GetArea(p, triangle.B, triangle.C) + Triangle.GetArea(p, triangle.C, triangle.A); if (sum >= area - 1 && sum <= area + 1) { _buffer[j, i].BackColor = fill.GetColor(i, j); } } DrawTriangle(triangle, border); }
/// <summary> /// Fills the entire buffer with a brush. /// </summary> /// <param name="brush">The brush to fill the buffer with.</param> public unsafe void ClearBrush(BufferBrush brush) { for (int i = _width - 1; i >= 0; i--) for (int j = _height - 1; j >= 0; j--) { _buffer[j, i].ForeColor = brush.GetColor(i, j); _buffer[j, i].BackColor = brush.GetColor(i, j); _buffer[j, i].CharData = '\0'; } }
/// <summary> /// Flood fills a closed region containing the specified coordinates with a brush. /// </summary> /// <param name="x">The X coordinate to begin filling at.</param> /// <param name="y">The Y coordinate to begin filling at.</param> /// <param name="brush">The brush to fill the region with.</param> public void FloodFill(int x, int y, BufferBrush brush) { if (!InBounds(x, y)) return; var initColor = _buffer[y, x].BackColor; if (brush.GetColor(x,y) == initColor) return; List<Point> queue = new List<Point>(32); queue.Add(new Point(x, y)); Point p; int w, e, j; for (int i = 0; i < queue.Count; i++) { p = queue[i]; w = e = p.X; while (w - 1 >= 0) { if (_buffer[p.Y, w - 1].BackColor == initColor) { w--; } else { break; } } while (e + 1 < _width) { if (_buffer[p.Y, e + 1].BackColor == initColor) { e++; } else { break; } } for (j = w; j <= e; j++) { _buffer[p.Y, j].BackColor = brush.GetColor(j, p.Y); if (p.Y + 1 < _height) { if (_buffer[p.Y + 1, j].BackColor == initColor) { queue.Add(new Point(j, p.Y + 1)); } } if (p.Y - 1 >= 0) { if (_buffer[p.Y - 1, j].BackColor == initColor) { queue.Add(new Point(j, p.Y - 1)); } } } } }
/// <summary> /// Draws text to a buffer using the specified settings. /// </summary> /// <param name="buffer">The buffer to draw to.</param> /// <param name="text">The text to draw.</param> /// <param name="position">The position of the text.</param> /// <param name="brush">The brush to draw the text with.</param> /// <param name="alignment">The alignment of the text relative to its position.</param> public void Draw(ConsoleBuffer buffer, string text, Point position, BufferBrush brush, Alignment alignment) { int // Character offsets mx = 0, my = 0; Point p = new Point(); Point pc = new Point(); foreach(char c in text) { p.X = alignment == Alignment.Left ? mx : -CharWidth - mx; p.Y = my; p = p + position; if (c == '\n') { mx = 0; my += CharHeight + 1; } else if (!Char.IsControl(c)) { for (int i = 0; i < glyphs[c].Length; i++) { if (c > glyphs.Length) continue; if (glyphs[c] == null) continue; pc.Y = i; for(int j = 0; j < glyphs[c][i].Length; j++) { if (glyphs[c][i] == null) continue; if (!glyphs[c][i][j]) continue; pc.X = j; buffer.SetUnitBackColor(p + pc, brush.GetColor(p.X + pc.X, p.Y + pc.Y)); } } mx += CharWidth + 1; } } }