/// <summary> /// Reads cell matrix form the output buffer using the provided rectangle. /// </summary> /// <param name="region"></param> /// <returns></returns> public CellBuffer ReadOutput(Region region) { var handle = GetOutputBuffer(); //Get len of X coordinate, the plan here is to partition by Y var sizeOfX = (region.Width - region.Left + 1) * 4; //partition by Y coordinate. var partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX)); int sizeOfY = (region.Height - region.Top); //if Y is smaller then the partition by Y then we need //to set the partiton size to Y size. if (sizeOfY < partitionY) { partitionY = sizeOfY; } ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD(); bufferCoord.X = 0; bufferCoord.Y = 0; ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD(); bufferSize.X = (short)(region.Width - region.Left); CellBuffer cells = new CellBuffer(sizeOfY, bufferSize.X); int cursor = 0; int i = 0; do { i += partitionY; //the size of the Y coordinate is always the size of the buffer. bufferSize.X = (short)(region.Width - region.Left); bufferSize.Y = (short)partitionY; //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer. if (i > sizeOfY) { int diff = i - sizeOfY; bufferSize.Y = (short)(partitionY - diff); } //Fill the buffer part. ConsoleHostNativeMethods.SMALL_RECT readRegion = new ConsoleHostNativeMethods.SMALL_RECT(); readRegion.Left = (short)region.Left; readRegion.Top = (short)region.Top; readRegion.Right = (short)(region.Left + bufferSize.X); readRegion.Bottom = (short)(region.Top + bufferSize.Y); ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[bufferSize.X * bufferSize.Y]; buffer = DotConsoleNative.ReadConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref readRegion); //Fill the output buffer cells. int idx = 0; for (int k = cursor; k < bufferSize.Y; k++) { for (int n = 0; n < bufferSize.X; n++) { cells.Cells[k, n].Attributes = buffer[idx].Attributes; cells.Cells[k, n].Char = buffer[idx].UnicodeChar; idx++; } cursor = k; } }while (i < sizeOfY); return(cells); }
public void WriteOutput(Coordinates orgin, CellBuffer cellBuffer) { var handle = GetOutputBuffer(); //Get len of X coordinate, the plan here is to partition by Y var sizeOfX = cellBuffer.GetLengthOfX() * 4; //partition by Y coordinate. int partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX)); var sizeOfY = cellBuffer.GetLengthOfY(); //if Y is smaller then the partition by Y then we need //to set the partiton size to Y size. if (sizeOfY < partitionY) { partitionY = sizeOfY; } //Get partitoned buffer size. int charBufferSize = (int)(partitionY * cellBuffer.GetLengthOfX()); int cursor = 0; int i = 0; do { i += partitionY; //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer. if (i > sizeOfY) { int diff = i - sizeOfY; i = i - diff; } //Fill the buffer part. ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[charBufferSize]; int idx = 0; for (int y = cursor; y < i; y++) { for (int x = 0; x < cellBuffer.GetLengthOfX(); x++) { var cellToWrite = cellBuffer[y, x]; if (cellToWrite.Attributes == 0) { //Don't set the foreground color for empty cells this will force the ConsoleHost //to do a very expensive calculation for each cell and slow things down. cellToWrite.Attributes = (ushort)DotConsoleNative.ToNativeConsoleColor(0, BackgroundColor); } buffer[idx].Attributes = cellToWrite.Attributes; buffer[idx].UnicodeChar = cellToWrite.Char; idx++; } } ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD(); bufferSize.X = (short)cellBuffer.GetLengthOfX(); bufferSize.Y = (short)partitionY; ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD(); bufferCoord.X = 0; bufferCoord.Y = 0; ConsoleHostNativeMethods.SMALL_RECT writeRegion = new ConsoleHostNativeMethods.SMALL_RECT(); writeRegion.Left = (short)orgin.X; writeRegion.Top = (short)(orgin.Y + cursor); writeRegion.Right = (short)(orgin.X + bufferSize.X); writeRegion.Bottom = (short)(orgin.Y + cursor + bufferSize.Y); DotConsoleNative.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion); cursor = i; }while (i < sizeOfY); }