internal void Render(Region window, DotConsoleRegion owner) { int height = Options.Orgin.Y + window.Top + (contentBuffer.GetLengthOfY()); int width = Options.Orgin.X + window.Left + (contentBuffer.GetLengthOfX()); int top = Options.Orgin.Y + window.Top; int left = Options.Orgin.X + window.Left; //If we're rendering at the bottom the orgin moves the content up. if (Options.Position == ContentPosition.Bottom) { height = window.Height - Options.Orgin.Y; int sizeOfY = contentBuffer.GetLengthOfY(); if (sizeOfY < window.Height) { top = window.Height - Options.Orgin.Y - (contentBuffer.GetLengthOfY()); } } if (Options.WillScrollContent == true) { top = Options.Orgin.Y; } //Scrollable content regions will not move with the window so theres no point to save state. else { savedContentBuffer = null; if (owner != null) { savedContentBuffer = Restore(owner, new Region() { Left = left, Top = top, Height = height, Width = width }); } else { savedContentBuffer = Renderer.ReadOutput(new Region() { Left = left, Top = top, Height = height, Width = width }); } } savedCoordsWithOffset.X = left; savedCoordsWithOffset.Y = top; if (owner != null) { Merge(owner.contentBuffer, this.contentBuffer); } else { Renderer.WriteOutput(savedCoordsWithOffset, this.contentBuffer); } }
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); }