Skip to content

Commit

Permalink
move to lower level renderer (no more textbox)
Browse files Browse the repository at this point in the history
  • Loading branch information
doubleyewdee committed Nov 21, 2018
1 parent 1e74379 commit 560e684
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 38 deletions.
20 changes: 13 additions & 7 deletions src/ConsoleBuffer/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,13 @@ private void HandleControlCharacter(ControlCharacterCommand.ControlCode code)
break;
case ControlCharacterCommand.ControlCode.FF: // NB: could clear screen with this if we were so inclined. apparently xterm treats this as LF though, let's emulate.
case ControlCharacterCommand.ControlCode.LF:
if (this.currentLine == this.lines.Count - 1)
if (this.currentLine == short.MaxValue)
{
// XXX: perf nightmare, need to turn lines into a circular buffer probs.
this.lines.RemoveAt(0);
this.lines.Add(new Line());
}
else if (this.currentLine == this.lines.Count - 1)
{
this.lines.Add(new Line());
}
Expand All @@ -149,20 +155,20 @@ public void Render(IRenderTarget target)
{
lock (this.renderLock)
{
for (var x = 0; x < this.Height; ++x)
for (var y = 0; y < this.Height; ++y)
{
var renderLine = this.bufferTopVisibleLine + x;
var renderLine = this.bufferTopVisibleLine + y;
var line = renderLine < this.lines.Count ? this.lines[renderLine] : Line.Empty;
short y = 0;
short x = 0;
foreach (var c in line)
{
target.RenderCharacter(c, x, y);
++y;
++x;
}
while (y < this.Width)
while (x < this.Width)
{
target.RenderCharacter(new Character { Glyph = ' ' }, x, y);
++y;
++x;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/ConsoleBuffer/ConsoleWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,13 @@ private void ReadConsoleTask()
// this can happen when our parent disposes, safe to bail out silently.
return;
}
/*
catch (Exception ex) // XXX: this is some lousy logging I don't normally recommend, need to kill later.
{
Logger.Verbose(ex.ToString());
throw;
}
*/
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/ConsoleBuffer/IRenderTarget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ public interface IRenderTarget
/// <summary>
/// Instructs the target to render the character 'c' at x/y coordinates.
/// </summary>
/// <param name="c">Character to render.</param>
/// <param name="x">Horizontal offset.</param>
/// <param name="y">Vertical offset.</param>
/// <param name="c">Character to render.</param>
void RenderCharacter(Character c, int x, int y);
}
}
4 changes: 2 additions & 2 deletions src/condo/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
xmlns:local="clr-namespace:condo"
mc:Ignorable="d"
Title="MainWindow" SizeToContent="WidthAndHeight">
<Grid>
<TextBox Background="Black" Foreground="Gray" Name="stuff" FontFamily="Consolas" FontSize="14" IsReadOnly="True" />
<Grid Background="Black">
<Canvas Name="screenCanvas" Background="Black" />
</Grid>
</Window>
41 changes: 13 additions & 28 deletions src/condo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace condo
{
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using System.Windows;
Expand All @@ -13,7 +14,7 @@
/// </summary>
public partial class MainWindow : Window, IRenderTarget
{
private DpiScale dpiInfo;
private Screen screen;
private ConsoleWrapper console;
private KeyHandler keyHandler;
private Character[,] characters;
Expand All @@ -26,36 +27,24 @@ public MainWindow()
System.Diagnostics.Debugger.Launch();
}


private void UpdateContents(object sender, PropertyChangedEventArgs args)
{
this.console.Buffer.Render(this);
this.Dispatcher.InvokeAsync(() => this.Redraw());
}

private Size DetermineSize()
{
DpiScale dpi = this.dpiInfo;

// because we only ever expect to work with monospace fonts we can extrapolate from any single character.
// lord help if someone gets real excited about proportional font console.
var sampleText = new FormattedText("x", CultureInfo.CurrentUICulture, FlowDirection.LeftToRight,
new Typeface(this.stuff.FontFamily, this.stuff.FontStyle, this.stuff.FontWeight, this.stuff.FontStretch),
this.stuff.FontSize, Brushes.Black, dpi.PixelsPerDip);

return new Size(sampleText.Width * this.console.Width, sampleText.Height * this.console.Height);
this.Dispatcher.InvokeAsync(() => this.Redraw());
}

private void OnLoaded(object sender, RoutedEventArgs e)
{
this.dpiInfo = VisualTreeHelper.GetDpi(this);
this.screen = new Screen();
this.screenCanvas.Children.Add(this.screen);
this.screenCanvas.Width = this.screen.Width;
this.screenCanvas.Height = this.screen.Height;

this.console = TerminalManager.Instance.GetOrCreate(0, "cmd.exe");
this.keyHandler = new KeyHandler(this.console);

var stuffSize = this.DetermineSize();
this.stuff.Height = stuffSize.Height;
this.stuff.Width = stuffSize.Width;

this.characters = new Character[this.console.Height, this.console.Width];
this.characters = new Character[this.console.Width, this.console.Height];
this.Redraw();

this.console.PropertyChanged += this.UpdateContents;
Expand All @@ -82,17 +71,13 @@ private void HandleClosing(object sender, CancelEventArgs e)

private void Redraw()
{
var sb = new StringBuilder();
for (var x = 0; x < this.console.Height; ++x)
for (var x = 0; x < this.console.Width; ++x)
{
for (var y = 0; y < this.console.Width; ++y)
for (var y = 0; y < this.console.Height; ++y)
{
sb.Append((char)this.characters[x, y].Glyph);
this.screen.SetCellCharacter(x, y, (char)this.characters[x, y].Glyph);
}
sb.Append('\n');
}

this.stuff.Text = sb.ToString();
}

public void RenderCharacter(Character c, int x, int y)
Expand Down
96 changes: 96 additions & 0 deletions src/condo/Screen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace condo
{
public sealed class Screen : FrameworkElement
{
private VisualCollection cells;
private DpiScale dpiInfo;
private readonly GlyphTypeface typeface;
private readonly int fontSize = 14;
private readonly double cellWidth, cellHeight;
private readonly Point baselineOrigin;
private readonly Rect cellRectangle;
private int horizontalCells, verticalCells;

public Screen() : this(80, 25) { }

public Screen(int width, int height)
{
this.cells = new VisualCollection(this);
if (!new Typeface("Consolas").TryGetGlyphTypeface(out this.typeface))
{
throw new InvalidOperationException("Could not get desired font.");
}

this.horizontalCells = width;
this.verticalCells = height;

this.cellWidth = this.typeface.AdvanceWidths[0] * this.fontSize;
this.cellHeight = this.typeface.Height * this.fontSize;
this.baselineOrigin = new Point(0, this.typeface.Baseline * this.fontSize);
this.cellRectangle = new Rect(new Size(this.cellWidth, this.cellHeight));

this.dpiInfo = VisualTreeHelper.GetDpi(this);
this.Resize();
}

protected override int VisualChildrenCount => this.cells.Count;

protected override Visual GetVisualChild(int index)
{
return this.cells[index];
}

protected override Size MeasureOverride(Size availableSize)
{
return new Size(this.cellWidth * this.horizontalCells, this.cellHeight * this.verticalCells);
}

private void Resize()
{
this.cells.Clear();
for (var y = 0; y < this.verticalCells; ++y)
{
for (var x = 0; x < this.horizontalCells; ++x)
{
var dv = new DrawingVisual();
dv.Offset = new Vector(x * this.cellWidth, y * this.cellHeight);
this.cells.Add(dv);
}
}

this.Width = this.horizontalCells * this.cellWidth;
this.Height = this.verticalCells * this.cellHeight;
}

private DrawingVisual GetCell(int x, int y)
{
return this.cells[x + y * this.horizontalCells] as DrawingVisual;
}

public void SetCellCharacter(int x, int y, char c)
{
using (var dc = this.GetCell(x, y).RenderOpen())
{
GlyphRun gr;
try
{
gr = new GlyphRun(this.typeface, 0, false, this.fontSize, (float)this.dpiInfo.PixelsPerDip, new[] { this.typeface.CharacterToGlyphMap[c] },
this.baselineOrigin, new[] { 0.0 }, new[] { new Point(0, 0) }, null, null, null, null, null);
}
catch (KeyNotFoundException)
{
gr = new GlyphRun(this.typeface, 0, false, this.fontSize, (float)this.dpiInfo.PixelsPerDip, new[] { this.typeface.CharacterToGlyphMap[0] },
this.baselineOrigin, new[] { 0.0 }, new[] { new Point(0, 0) }, null, null, null, null, null);
}

dc.DrawRectangle(Brushes.Black, null, new Rect(new Point(0, 0), new Point(this.cellWidth, this.cellHeight)));
dc.DrawGlyphRun(Brushes.Gray, gr);
}
}
}
}
1 change: 1 addition & 0 deletions src/condo/condo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="KeyHandler.cs" />
<Compile Include="Screen.cs" />
<Compile Include="TerminalManager.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
Expand Down

0 comments on commit 560e684

Please sign in to comment.