Skip to content

Commit

Permalink
sort of vaguely have bold working(!)
Browse files Browse the repository at this point in the history
  • Loading branch information
doubleyewdee committed Nov 27, 2018
1 parent 38e145e commit 7c34a5f
Show file tree
Hide file tree
Showing 8 changed files with 281 additions and 72 deletions.
42 changes: 28 additions & 14 deletions src/ConsoleBuffer/Buffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ namespace ConsoleBuffer
{
using System;
using System.ComponentModel;
using System.Text;

public sealed class Buffer : INotifyPropertyChanged
{
Expand Down Expand Up @@ -35,7 +36,7 @@ public sealed class Buffer : INotifyPropertyChanged
/// <summary>
/// The xterm palette to use when mapping color names/offsets to RGB values in characters.
/// </summary>
public XtermPalette Palette { get; set; }
public XtermPalette Palette { get; set; } = XtermPalette.Default;

private int topVisibleLine;
private int bottomVisibleLine;
Expand All @@ -62,7 +63,7 @@ private int CurrentLine
/// </summary>
public int BufferSize { get { return this.lines.Size; } }

public string Title { get; private set; }
public string Title { get; private set; } = string.Empty;

public Buffer(short width, short height)
{
Expand All @@ -73,7 +74,7 @@ public Buffer(short width, short height)

var defaultChar = new Character()
{
Options = Character.BasicColorOptions(Character.White, Character.Black),
Options = Character.BasicColorOptions(Commands.SetGraphicsRendition.Colors.White, Commands.SetGraphicsRendition.Colors.Black),
Glyph = 0x20,
};

Expand All @@ -87,6 +88,15 @@ public Buffer(short width, short height)
this.bottomVisibleLine = this.MaxCursorY;
}

/// <summary>
/// Append the given string to the buffer. The string will be converted to UTF8 and then written to the buffer as usual.
/// </summary>
public void AppendString(string str)
{
var strBytes = Encoding.UTF8.GetBytes(str);
this.Append(strBytes, strBytes.Length);
}

public void Append(byte[] bytes, int length)
{
lock (this.renderLock)
Expand Down Expand Up @@ -395,7 +405,11 @@ private void HandleSetCursorPosition(Commands.SetCursorPosition scp)

private void HandleSGR(Commands.SetGraphicsRendition sgr)
{
var updatedCell = this.lines[this.CurrentLine].Get(this.cursorX);
if (sgr.ForegroundBright == Commands.SetGraphicsRendition.FlagValue.Set) updatedCell.Options |= Character.ForegroundBrightFlag;
if (sgr.ForegroundBright == Commands.SetGraphicsRendition.FlagValue.Unset) updatedCell.Options &= ~Character.ForegroundBrightFlag;

this.lines[this.CurrentLine].Set(this.cursorX, updatedCell);
}

private void HandleSetMode(Commands.SetMode sm)
Expand Down Expand Up @@ -453,36 +467,36 @@ private Character ColorCharacter(Character ch)

if (ch.HasBasicForegroundColor)
{
ret.Foreground = this.GetColorInfoFromBasicColor(ret.ForegroundColor, ret.ForegroundBright);
ret.Foreground = this.GetColorInfoFromBasicColor(ret.BasicForegroundColor, ret.ForegroundBright);
}
if (ch.HasBasicBackgroundColor)
{
ret.Background = this.GetColorInfoFromBasicColor(ret.BackgroundColor, ret.BackgroundBright);
ret.Background = this.GetColorInfoFromBasicColor(ret.BasicBackgroundColor, ret.BackgroundBright);
}

return ret;
}

private Character.ColorInfo GetColorInfoFromBasicColor(short basicColor, bool isBright)
private Character.ColorInfo GetColorInfoFromBasicColor(Commands.SetGraphicsRendition.Colors basicColor, bool isBright)
{
var paletteOffset = isBright ? 8 : 0;
switch (basicColor)
{
case Character.Black:
case Commands.SetGraphicsRendition.Colors.Black:
return this.Palette[0 + paletteOffset];
case Character.Red:
case Commands.SetGraphicsRendition.Colors.Red:
return this.Palette[1 + paletteOffset];
case Character.Green:
case Commands.SetGraphicsRendition.Colors.Green:
return this.Palette[2 + paletteOffset];
case Character.Yellow:
case Commands.SetGraphicsRendition.Colors.Yellow:
return this.Palette[3 + paletteOffset];
case Character.Blue:
case Commands.SetGraphicsRendition.Colors.Blue:
return this.Palette[4 + paletteOffset];
case Character.Magenta:
case Commands.SetGraphicsRendition.Colors.Magenta:
return this.Palette[5 + paletteOffset];
case Character.Cyan:
case Commands.SetGraphicsRendition.Colors.Cyan:
return this.Palette[6 + paletteOffset];
case Character.White:
case Commands.SetGraphicsRendition.Colors.White:
return this.Palette[7 + paletteOffset];
default:
throw new InvalidOperationException("Unexpected color value.");
Expand Down
112 changes: 62 additions & 50 deletions src/ConsoleBuffer/Character.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,65 @@ public struct ColorInfo
public byte R;
public byte G;
public byte B;
public override string ToString()
{
return $"#{this.R:x2}{this.G:x2}{this.B:x2}";
}
}

public ColorInfo Foreground { get; set; }
public ColorInfo Background { get; set; }

// traditional colors occupy 3 bits, we keep two sets (foreground + background).
public const short Black = 0x0000;
public const short Red = 0x0001;
public const short Green = 0x0002;
public const short Yellow = 0x0003;
public const short Blue = 0x0004;
public const short Magenta = 0x0005;
public const short Cyan = 0x0006;
public const short White = 0x0007;
// the actual colors are declared in the SGR command.
private const short ForegroundColorMask = 0x0007;
private const short BackgroundBitShift = 3;
private const short BackgroundColorMask = ForegroundColorMask << BackgroundBitShift;
// flags
private const short ForegroundBasicColorFlag = 0x0001 << 6;
private const short BackgroundBasicColorFlag = 0x0002 << 6;
private const short ForegroundBrightFlag = 0x0004 << 6;
private const short BackgroundBrightFlag = 0x0008 << 6;
private const short UnderlineFlag = 0x0010 << 6;
private const short InverseFlag = 0x0020 << 6;
private const short ForegroundExplicitFlag = 0x0040 << 6;
private const short BackgroundExplicitFlag = 0x0080 << 6;
private const short ExplicitFlags = (ForegroundExplicitFlag | BackgroundBrightFlag);
private const short ForegroundExtendedFlag = 0x0100 << 6;
private const short BackgroundExtendedFlag = unchecked((short)(0x0200 << 6));
internal const short ForegroundBasicColorFlag = 0x0001 << 6;
internal const short BackgroundBasicColorFlag = 0x0002 << 6;
internal const short ForegroundBrightFlag = 0x0004 << 6;
internal const short BackgroundBrightFlag = 0x0008 << 6;
internal const short UnderlineFlag = 0x0010 << 6;
internal const short InverseFlag = 0x0020 << 6;
internal const short ForegroundExplicitFlag = 0x0040 << 6;
internal const short BackgroundExplicitFlag = 0x0080 << 6;
internal const short ExplicitFlags = (ForegroundExplicitFlag | BackgroundBrightFlag);
internal const short ForegroundExtendedFlag = 0x0100 << 6;
internal const short BackgroundExtendedFlag = unchecked((short)(0x0200 << 6));

public short Options;
internal short Options;

public static short BasicColorOptions(short foreground = -1, short background = -1)
internal static short BasicColorOptions(Commands.SetGraphicsRendition.Colors foreground = Commands.SetGraphicsRendition.Colors.None,
Commands.SetGraphicsRendition.Colors background = Commands.SetGraphicsRendition.Colors.None)
{
short options = 0;
if (foreground > -1)
if (foreground != Commands.SetGraphicsRendition.Colors.None)
{
#if DEBUG
if (foreground > White)
{
throw new ArgumentOutOfRangeException(nameof(foreground));
}
#endif
options |= (short)(foreground | ForegroundExplicitFlag | ForegroundBasicColorFlag);
options |= (short)((short)foreground | ForegroundExplicitFlag | ForegroundBasicColorFlag);
}
if (background > -1)
if (background != Commands.SetGraphicsRendition.Colors.None)
{
#if DEBUG
if (background > White)
{
throw new ArgumentOutOfRangeException(nameof(background));
}
#endif
options |= (short)((background << BackgroundBitShift) | BackgroundExplicitFlag | BackgroundBasicColorFlag);
options |= (short)(((short)background << BackgroundBitShift) | BackgroundExplicitFlag | BackgroundBasicColorFlag);
}

return options;
}

public short ForegroundColor => (short)(this.Options & ForegroundColorMask);
public bool HasBasicForegroundColor => (this.Options & ForegroundBasicColorFlag) != 0;
public short BackgroundColor => (short)(this.Options & BackgroundColorMask);
public bool HasBasicBackgroundColor => (this.Options & BackgroundBasicColorFlag) != 0;
public bool ForegroundBright => (this.Options & ForegroundBrightFlag) != 0;
public bool BackgroundBright => (this.Options & BackgroundBrightFlag) != 0;
public bool Underline => (this.Options & UnderlineFlag) != 0;
public bool Inverse => (this.Options & InverseFlag) != 0;
public bool ForegroundExplicit => (this.Options & ForegroundExplicitFlag) != 0;
public bool BackgroundExplicit => (this.Options & BackgroundExplicitFlag) != 0;
public bool ForegroundExtended => (this.Options & ForegroundExtendedFlag) != 0;
public bool BackgroundExtended => (this.Options & BackgroundExtendedFlag) != 0;
internal Commands.SetGraphicsRendition.Colors BasicForegroundColor => (Commands.SetGraphicsRendition.Colors)(this.Options & ForegroundColorMask);
internal bool HasBasicForegroundColor => (this.Options & ForegroundBasicColorFlag) != 0;
internal Commands.SetGraphicsRendition.Colors BasicBackgroundColor => (Commands.SetGraphicsRendition.Colors)(this.Options & BackgroundColorMask);
internal bool HasBasicBackgroundColor => (this.Options & BackgroundBasicColorFlag) != 0;
internal bool ForegroundBright => (this.Options & ForegroundBrightFlag) != 0;
internal bool BackgroundBright => (this.Options & BackgroundBrightFlag) != 0;
internal bool Underline => (this.Options & UnderlineFlag) != 0;
internal bool Inverse => (this.Options & InverseFlag) != 0;
internal bool ForegroundExplicit => (this.Options & ForegroundExplicitFlag) != 0;
internal bool BackgroundExplicit => (this.Options & BackgroundExplicitFlag) != 0;
internal bool ForegroundExtended => (this.Options & ForegroundExtendedFlag) != 0;
internal bool BackgroundExtended => (this.Options & BackgroundExtendedFlag) != 0;

public short InheritedOptions => (short)(this.Options & ~(ForegroundExplicitFlag | BackgroundExplicitFlag));
internal short InheritedOptions => (short)(this.Options & ~(ForegroundExplicitFlag | BackgroundExplicitFlag));

/// <summary>
/// The unicode glyph for this character.
Expand All @@ -101,5 +87,31 @@ public Character(Character parent)
this.Options = parent.Options;
this.Options &= ~ExplicitFlags;
}

public Character(Character parent, Commands.SetGraphicsRendition sgr)
: this(parent)
{
switch (sgr.ForegroundBright)
{
case Commands.SetGraphicsRendition.FlagValue.Set:
this.Options |= (ForegroundBrightFlag | ForegroundExplicitFlag);
break;
case Commands.SetGraphicsRendition.FlagValue.Unset:
this.Options &= ~ForegroundBrightFlag;
this.Options |= ForegroundExplicitFlag;
break;
}

switch (sgr.BackgroundBright)
{
case Commands.SetGraphicsRendition.FlagValue.Set:
this.Options |= (BackgroundBrightFlag | BackgroundExplicitFlag);
break;
case Commands.SetGraphicsRendition.FlagValue.Unset:
this.Options &= ~BackgroundBrightFlag;
this.Options |= BackgroundExplicitFlag;
break;
}
}
}
}
2 changes: 1 addition & 1 deletion src/ConsoleBuffer/Commands/ControlSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ namespace ConsoleBuffer.Commands
{
using System;
using System.Collections.Generic;
using System.Diagnostics;

public abstract class ControlSequence : Base
{
Expand Down Expand Up @@ -39,6 +38,7 @@ public static Base Create(char command, string bufferData)
public bool IsExtended { get; private set; }
protected IList<string> Parameters { get; private set; }
protected ControlSequence(string bufferData) : base(bufferData) { }

protected override void Parse(string bufferData)
{
if (bufferData.Length == 0)
Expand Down
61 changes: 59 additions & 2 deletions src/ConsoleBuffer/Commands/SetGraphicsRendition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,78 @@ public enum FlagValue
None,
}

public enum Colors : short
{
Black = 0,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
None,
}

public bool HaveBasicForeground { get; private set; }
public Colors BasicForegroundColor { get; private set; } = Colors.None;
public bool HaveForeground { get; private set; }
public Character.ColorInfo ForegroundColor { get; private set; }

public bool HaveBasicBackground { get; private set; }
public Colors BasicBackgroundColor { get; private set; } = Colors.None;
public bool HaveBackground { get; private set; }
public Character.ColorInfo BackgroundColor { get; private set; }

public FlagValue Bold { get; private set; }
public FlagValue ForegroundBright { get; private set; }
public FlagValue BackgroundBright { get; private set; }
public FlagValue Underline { get; private set; }
public FlagValue Inverse { get; private set; }

public SetGraphicsRendition(string bufferData) : base(bufferData)
{
this.Bold = FlagValue.None;
this.ForegroundBright = FlagValue.None;
this.BackgroundBright = FlagValue.None;
this.Underline = FlagValue.None;
this.Inverse = FlagValue.None;

if (this.Parameters.Count == 0)
{
this.SetDefault();
return;
}

var p = 0;
while (p < this.Parameters.Count)
{
switch (this.ParameterToNumber(p, defaultValue: -1))
{
case 0:
this.SetDefault();
break;
case 1:
this.ForegroundBright = FlagValue.Set;
break;
case 2:
case 22:
this.ForegroundBright = FlagValue.Unset;
break;
}

++p;
}
}

private void SetDefault()
{
this.ForegroundBright = FlagValue.Unset;
this.BackgroundBright = FlagValue.Unset;
this.Underline = FlagValue.Unset;
this.Inverse = FlagValue.Unset;
this.HaveForeground = this.HaveBackground = false;
this.HaveBasicForeground = this.HaveBasicBackground = true;
this.BasicForegroundColor = Colors.White;
this.BasicBackgroundColor = Colors.Black;
}
}
}
2 changes: 2 additions & 0 deletions src/ConsoleBuffer/XtermPalette.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace ConsoleBuffer
/// </summary>
public sealed class XtermPalette
{
public static readonly XtermPalette Default = new XtermPalette();

private struct XtermColor
{
public int Id;
Expand Down
2 changes: 1 addition & 1 deletion src/condo/Screen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public ConsoleBuffer.Buffer Buffer
}
}

private readonly XtermPalette palette = new XtermPalette();
private readonly XtermPalette palette = XtermPalette.Default;

private VisualCollection cells;
private DpiScale dpiInfo;
Expand Down
Loading

0 comments on commit 7c34a5f

Please sign in to comment.