Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update palette, fix cell drawing #7

Merged
merged 2 commits into from
Dec 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions src/ConsoleBuffer/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,33 @@ private Character.ColorInfo GetColorInfoFromBasicColor(Commands.SetGraphicsRendi
}
}

/// <summary>
/// Updates the colors of all cells in the buffer from the current palette if they have basic (16 color) values.
/// </summary>
public void UpdateBasicColorsFromPalette()
{
lock (this.renderLock)
{
for (var y = 0; y < this.BufferSize; ++y)
{
var line = this.lines[y];
for (var x = 0; x < line.Length; ++x)
{
var ch = line[x];
if (ch.HasBasicBackgroundColor)
{
ch.Background = this.GetColorInfoFromBasicColor(ch.BasicBackgroundColor, ch.BackgroundBright);
}
if (ch.HasBasicForegroundColor)
{
ch.Foreground = this.GetColorInfoFromBasicColor(ch.BasicForegroundColor, ch.ForegroundBright);
}
line[x] = ch;
}
}
}
}

/// <summary>
/// Render the currently "on-screen" area character-by-character onto the specified target.
/// </summary>
Expand Down
16 changes: 16 additions & 0 deletions src/ConsoleBuffer/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ public struct ColorInfo : IEquatable<ColorInfo>
public byte G;
public byte B;

public ColorInfo(string rgbValue)
{
this.R = this.G = this.B = 0;
if (rgbValue.Length != 7 || rgbValue[0] != '#')
{
throw new ArgumentException(nameof(rgbValue));
}
for (var i = 1; i < 7; ++i)
{
if (rgbValue[i] < '0' || rgbValue[i] > '9')
throw new ArgumentException(nameof(rgbValue));
}
}

public bool Equals(ColorInfo other)
{
return (this.R == other.R && this.G == other.G && this.B == other.B);
Expand Down Expand Up @@ -65,6 +79,8 @@ public override string ToString()
internal const short ForegroundExtendedFlag = 0x0040 << 6;
internal const short BackgroundExtendedFlag = 0x0080 << 6;

internal const short DefaultOptions = (0x7 | ForegroundBasicColorFlag | BackgroundBasicColorFlag);

internal short Options;

internal static short GetColorFlags(Commands.SetGraphicsRendition.Colors color, bool background)
Expand Down
9 changes: 8 additions & 1 deletion src/ConsoleBuffer/Line.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@ public sealed class Line : IEnumerable<Character>

public int Length => this.chars.Count;

// XXX: should probably remove users of Get/Set and just have them call this for clarity.
public Character this[int pos] { get => this.Get(pos); set => this.Set(pos, value); }

public Line()
{
var hintSize = 80;
this.chars = new List<Character>(hintSize);
this[0] = new Character { Glyph = 0x20, Options = Character.DefaultOptions };
}

/// <summary>
Expand All @@ -39,7 +43,10 @@ public Character Get(int pos)
return this.chars[pos];
}

return new Character { Glyph = 0x20 };
// for short lines we can lazily keep the attributes (specifically background) from whatever our last character was, assuming we had one.
var ch = this.chars.Count > 0 ? this.chars[this.chars.Count - 1] : new Character { Options = Character.DefaultOptions };
ch.Glyph = 0x20;
return ch;
}

/// <summary>
Expand Down
4 changes: 4 additions & 0 deletions src/ConsoleBuffer/XtermPalette.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ public Character.ColorInfo this[int id]
{
return this.colorPalette[id];
}
set
{
this.colorPalette[id] = value;
}
}

public Character.ColorInfo this[string name]
Expand Down
2 changes: 1 addition & 1 deletion 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 Background="Black">
<Grid>
<ScrollViewer Name="scrollViewer" CanContentScroll="true" IsDeferredScrollingEnabled="true" Focusable="False">
<local:Screen x:Name="screen" />
</ScrollViewer>
Expand Down
22 changes: 22 additions & 0 deletions src/condo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace condo
public partial class MainWindow : Window
{
private const int MinimumWindowsVersion = 17763;
private readonly XtermPalette mellowPalette;
private ConsoleWrapper console;
private KeyHandler keyHandler;

Expand All @@ -36,6 +37,27 @@ public MainWindow()
{
this.InitializeComponent();
this.Loaded += this.OnLoaded;

// XXX: lazy dark but not painfully bright palette
this.mellowPalette = new XtermPalette();
this.mellowPalette[0] = new Character.ColorInfo { R = 0x1d, G = 0x1f, B = 0x21 };
this.mellowPalette[1] = new Character.ColorInfo { R = 0xa5, G = 0x42, B = 0x42 };
this.mellowPalette[2] = new Character.ColorInfo { R = 0x8c, G = 0x94, B = 0x40 };
this.mellowPalette[3] = new Character.ColorInfo { R = 0xde, G = 0x93, B = 0x5f };
this.mellowPalette[4] = new Character.ColorInfo { R = 0x5f, G = 0x81, B = 0x9d };
this.mellowPalette[5] = new Character.ColorInfo { R = 0x85, G = 0x67, B = 0x8f };
this.mellowPalette[6] = new Character.ColorInfo { R = 0x5e, G = 0x8d, B = 0x87 };
this.mellowPalette[7] = new Character.ColorInfo { R = 0x70, G = 0x78, B = 0x80 };
this.mellowPalette[8] = new Character.ColorInfo { R = 0x37, G = 0x3b, B = 0x41 };
this.mellowPalette[9] = new Character.ColorInfo { R = 0xcc, G = 0x66, B = 0x66 };
this.mellowPalette[10] = new Character.ColorInfo { R = 0xb5, G = 0xbd, B = 0x68 };
this.mellowPalette[11] = new Character.ColorInfo { R = 0xf0, G = 0xc6, B = 0x74 };
this.mellowPalette[12] = new Character.ColorInfo { R = 0x81, G = 0xa2, B = 0xbe };
this.mellowPalette[13] = new Character.ColorInfo { R = 0xb2, G = 0x94, B = 0xbb };
this.mellowPalette[14] = new Character.ColorInfo { R = 0x8a, G = 0xbe, B = 0xb7 };
this.mellowPalette[15] = new Character.ColorInfo { R = 0xc5, G = 0xc8, B = 0xc6 };

this.screen.Palette = this.mellowPalette;
}

private void OnLoaded(object sender, RoutedEventArgs e)
Expand Down
24 changes: 22 additions & 2 deletions src/condo/Screen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,20 @@ public ConsoleBuffer.Buffer Buffer
}
}

private readonly XtermPalette palette = XtermPalette.Default;
private XtermPalette palette = XtermPalette.Default;
public XtermPalette Palette
{
get
{
return this.palette;
}
set
{
this.palette = value;
this.buffer.Palette = this.palette;
this.buffer.UpdateBasicColorsFromPalette();
}
}

private VisualCollection cells;
private DpiScale dpiInfo;
Expand All @@ -45,6 +58,7 @@ public ConsoleBuffer.Buffer Buffer
private readonly double cellWidth, cellHeight;
private readonly Point baselineOrigin;
private readonly Rect cellRectangle;
private readonly GuidelineSet cellGuidelines;
private int horizontalCells, verticalCells;
private DrawCharacter[,] characters;
bool cursorInverted;
Expand All @@ -71,6 +85,7 @@ public Screen() : this(new ConsoleBuffer.Buffer(80, 25))

public Screen(ConsoleBuffer.Buffer buffer)
{
this.UseLayoutRounding = true;
this.dpiInfo = VisualTreeHelper.GetDpi(this);
this.cells = new VisualCollection(this);
if (!new Typeface("Consolas").TryGetGlyphTypeface(out this.typeface))
Expand All @@ -81,6 +96,8 @@ public Screen(ConsoleBuffer.Buffer buffer)
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.cellGuidelines = new GuidelineSet(new[] { this.cellRectangle.Left, this.cellRectangle.Right }, new[] { this.cellRectangle.Top, this.cellRectangle.Bottom });
this.cellGuidelines.Freeze();

this.Buffer = buffer;
this.cursorBlinkWatch.Start();
Expand Down Expand Up @@ -198,9 +215,12 @@ public void SetCellCharacter(int x, int y, bool invert = false)

using (var dc = this.GetCell(x, y).RenderOpen())
{
var backgroundRectangle = new Rect(0, 0, this.cellWidth, this.cellHeight);
var gs = new GuidelineSet();
dc.PushGuidelineSet(this.cellGuidelines);
var backgroundBrush = this.brushCache.GetBrush(ch.Background.R, ch.Background.G, ch.Background.B);
var foregroundBrush = this.brushCache.GetBrush(ch.Foreground.R, ch.Foreground.G, ch.Foreground.B);
dc.DrawRectangle(!invert ? backgroundBrush : foregroundBrush, null, new Rect(new Point(0, 0), new Point(this.cellWidth, this.cellHeight)));
dc.DrawRectangle(!invert ? backgroundBrush : foregroundBrush, null, this.cellRectangle);

if (ch.Foreground == ch.Background) return; // no need to draw same color glyph.

Expand Down