From d86c63a1baee831ff0ce58ddea94841cbc5347ca Mon Sep 17 00:00:00 2001 From: Evgeny Gorbovoy Date: Fri, 5 Jan 2024 18:38:23 +0100 Subject: [PATCH] =?UTF-8?q?This=20commit=20introduces=20support=20for=20ta?= =?UTF-8?q?b=20and=20newline=20characters=20in=20the=20=E2=80=A6=20(#113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * This commit introduces support for tab and newline characters in the DrawingContextImpl class. The update will handle these characters during draw operations, translating tab characters into a sequence of spaces and newline characters into a 'no-op' (no operation) at this stage. * Refactor drawing context implementation The unused namespace `System.Text` was removed from the `DrawingContextImpl` class. Also, the handling of tab spaces was adjusted; instead of incrementing the current position one by one, we now increment it by the `tabSize` in one go. This also involved creating a constant for the `tabSize`. Additionally, comments related to resharper's handling of closure were added. * Automated JetBrains cleanup * Implement clipping in DrawingContextImpl The implementation of clipping was added in the DrawingContextImpl.cs. This ensures the pixel buffer coordinates stay within the defined bounds when rendering text, specifically with tabs, thereby improving the rendering process and accuracy. --- .../Drawing/DrawingContextImpl.cs | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs index f5fde7e0..4f047829 100644 --- a/src/Consolonia.Core/Drawing/DrawingContextImpl.cs +++ b/src/Consolonia.Core/Drawing/DrawingContextImpl.cs @@ -381,11 +381,13 @@ void DrawPixelAndMoveHead(int count) if (!Transform.IsTranslateOnly()) ConsoloniaPlatform.RaiseNotSupported(15); Point whereToDraw = origin.Transform(Transform); + int currentXPosition = 0; //todo: support surrogates for (int i = 0; i < str.Length; i++) { - Point characterPoint = whereToDraw.Transform(Matrix.CreateTranslation(i, 0)); + Point characterPoint = whereToDraw.Transform(Matrix.CreateTranslation(currentXPosition++, 0)); + // ReSharper disable AccessToModifiedClosure CurrentClip.ExecuteWithClipping(characterPoint, () => { ConsoleColor foregroundColor = consoleColorBrush.Color; @@ -411,12 +413,48 @@ void DrawPixelAndMoveHead(int count) } } - // ReSharper disable once AccessToModifiedClosure //todo: pass as a parameter - var consolePixel = new Pixel(str[i], foregroundColor); + char character = str[i]; - _pixelBuffer.Set((PixelBufferCoordinate)characterPoint, - (oldPixel, cp) => oldPixel.Blend(cp), consolePixel); + switch (character) + { + case '\t': + { + const int tabSize = 8; + var consolePixel = new Pixel(' ', foregroundColor); + for (int j = 0; j < tabSize; j++) + { + Point newCharacterPoint = characterPoint.WithX(characterPoint.X + j); + CurrentClip.ExecuteWithClipping(newCharacterPoint, () => + { + _pixelBuffer.Set((PixelBufferCoordinate)characterPoint.WithX(characterPoint.X + j), + (oldPixel, cp) => oldPixel.Blend(cp), consolePixel); + }); + } + + + currentXPosition += tabSize - 1; + } + break; + case '\n': + { + /* it's not clear if we need to draw anything. Cursor can be placed at the end of the line + var consolePixel = new Pixel(' ', foregroundColor); + + _pixelBuffer.Set((PixelBufferCoordinate)characterPoint, + (oldPixel, cp) => oldPixel.Blend(cp), consolePixel);*/ + } + break; + default: + { + var consolePixel = new Pixel(character, foregroundColor); + + _pixelBuffer.Set((PixelBufferCoordinate)characterPoint, + (oldPixel, cp) => oldPixel.Blend(cp), consolePixel); + } + break; + } }); + // ReSharper restore AccessToModifiedClosure } } }