예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }