public static void PrintHeader(ICellSurface target, SadConsole.UI.Colors themeColors, Point position, int totalWidth, string text) { totalWidth = totalWidth - text.Length - 3; if (totalWidth < 0) { throw new Exception("Header text too small"); } var lineText = ColoredString.FromGradient( new Gradient( new[] { themeColors.White, themeColors.White, themeColors.Gray, themeColors.Gray, themeColors.GrayDark, themeColors.GrayDark }, new[] { 0f, 0.3f, 0.31f, 0.65f, 0.66f, 1f }), new string((char)196, totalWidth)); target.Print(position.X, position.Y, new ColoredString(new ColoredGlyph(themeColors.White, Color.Transparent, 196)) + new ColoredString(new ColoredGlyph(themeColors.Cyan, Color.Transparent, 254)) + new ColoredString(text, themeColors.Title, Color.Transparent) + new ColoredString(new ColoredGlyph(themeColors.Cyan, Color.Transparent, 254)) ); var targetPosition = Point.FromIndex(position.ToIndex(target.Width) + text.Length + 3, target.Width); target.Print(targetPosition.X, targetPosition.Y, lineText); }
/// <summary> /// Creates a new console using the existing surface. /// </summary> /// <param name="surface">The surface.</param> /// <param name="font">The font to use with the surface.</param> /// <param name="fontSize">The font size.</param> public Console(ICellSurface surface, IFont font = null, Point?fontSize = null) : base(surface, font, fontSize) { Cursor = new Cursor() { IsVisible = false, IsEnabled = false }; SadComponents.Add(Cursor); UseKeyboard = Settings.DefaultConsoleUseKeyboard; }
public BorderComponent(int[] connectedLineStyle, Color foreground, Color background) { if (!ICellSurface.ValidateLineStyle(connectedLineStyle)) { throw new ArgumentException("The connected line array is invalid.", nameof(connectedLineStyle)); } _borderGlyphs = connectedLineStyle; _borderCellStyle = new ColoredGlyph(foreground, background); }
private ParseCommandBase CustomParseCommand(string command, string parameters, ColoredGlyph[] glyphString, ICellSurface surface, ParseCommandStacks commandStacks) { switch (command) { case "t": return(new ParseCommandRetext(parameters)); default: return(null);; } }
/// <inheritdoc /> public override void Build(ref ColoredString.ColoredGlyphEffect glyphState, ColoredString.ColoredGlyphEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, string processedString, ParseCommandStacks commandStack) { glyphState.Mirror = Mirror; if (_counter != -1) { _counter--; if (_counter == 0) { commandStack.RemoveSafe(this); } } }
/// <inheritdoc /> public override void Build(ref ColoredString.ColoredGlyphEffect glyphState, ColoredString.ColoredGlyphEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, string processedString, ParseCommandStacks commandStack) { if (CommandType == CommandTypes.Background) { glyphState.Background = GradientString[Length - _counter].Foreground; } else { glyphState.Foreground = GradientString[Length - _counter].Foreground; } _counter--; if (_counter == 0) { commandStack.RemoveSafe(this); } }
public void Surface_Equals(ICellSurface surface1, ICellSurface surface2) { Assert.AreEqual(surface1.View, surface2.View); Assert.AreEqual(surface1.Area, surface2.Area); Assert.AreEqual(surface1.Count, surface2.Count); Assert.AreEqual(surface1.DefaultBackground, surface2.DefaultBackground); Assert.AreEqual(surface1.DefaultForeground, surface2.DefaultForeground); Assert.AreEqual(surface1.DefaultGlyph, surface2.DefaultGlyph); Assert.AreEqual(surface1.IsScrollable, surface2.IsScrollable); Assert.AreEqual(surface1.TimesShiftedDown, surface2.TimesShiftedDown); Assert.AreEqual(surface1.TimesShiftedLeft, surface2.TimesShiftedLeft); Assert.AreEqual(surface1.TimesShiftedRight, surface2.TimesShiftedRight); Assert.AreEqual(surface1.TimesShiftedUp, surface2.TimesShiftedUp); Assert.AreEqual(surface1.UsePrintProcessor, surface2.UsePrintProcessor); for (int i = 0; i < surface1.Count; i++) { Assert.IsTrue(surface1[i].Matches(surface2[i])); } }
/// <inheritdoc /> public override void Build(ref ColoredString.ColoredGlyphEffect glyphState, ColoredString.ColoredGlyphEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, string processedString, ParseCommandStacks commandStack) { if (RandomGlyph) { glyphState.GlyphCharacter = (char)SadConsole.GameHost.Instance.Random.Next(RandomGlyphMin, RandomGlyphMax); } else { glyphState.GlyphCharacter = Glyph; } if (_counter != -1) { _counter--; } if (_counter == 0) { commandStack.RemoveSafe(this); } }
public DrawCallSurface(ICellSurface surface, Point position) { _surface = surface; _position = position; }
/// <summary> /// Creates a colored string by parsing commands embedded in the string. /// </summary> /// <param name="value">The string to parse.</param> /// <param name="surfaceIndex">Index of where this string will be printed.</param> /// <param name="surface">The surface the string will be printed to.</param> /// <param name="initialBehaviors">Any initial defaults.</param> /// <returns>The finalized string.</returns> public static ColoredString Parse(string value, int surfaceIndex = -1, ICellSurface surface = null, ParseCommandStacks initialBehaviors = null) { ParseCommandStacks commandStacks = initialBehaviors ?? new ParseCommandStacks(); List <ColoredGlyphEffect> glyphs = new List <ColoredGlyphEffect>(value.Length); for (int i = 0; i < value.Length; i++) { ColoredGlyphEffect[] existingGlyphs = glyphs.ToArray(); if (value[i] == '`' && i + 1 < value.Length && value[i + 1] == '[') { continue; } if (value[i] == '[' && (i == 0 || value[i - 1] != '`')) { try { if (i + 4 < value.Length && value[i + 1] == 'c' && value[i + 2] == ':' && value.IndexOf(']', i + 2) != -1) { int commandExitIndex = value.IndexOf(']', i + 2); string command = value.Substring(i + 3, commandExitIndex - (i + 3)); string commandParams = ""; if (command.Contains(" ")) { string[] commandSections = command.Split(new char[] { ' ' }, 2); command = commandSections[0].ToLower(); commandParams = commandSections[1]; } // Check for custom command ParseCommandBase commandObject = CustomProcessor?.Invoke(command, commandParams, existingGlyphs, surface, commandStacks); // No custom command found, run build in ones if (commandObject == null) { switch (command) { case "recolor": case "r": commandObject = new ParseCommandRecolor(commandParams); break; case "mirror": case "m": commandObject = new ParseCommandMirror(commandParams); break; case "undo": case "u": commandObject = new ParseCommandUndo(commandParams, commandStacks); break; case "grad": case "g": commandObject = new ParseCommandGradient(commandParams); break; case "blink": case "b": commandObject = new ParseCommandBlink(commandParams, existingGlyphs, commandStacks, surface); break; case "sglyph": case "sg": commandObject = new ParseCommandSetGlyph(commandParams); break; case "ceffect": case "ce": commandObject = new ParseCommandClearEffect(commandParams, commandStacks); break; default: break; } } if (commandObject != null && commandObject.CommandType != CommandTypes.Invalid) { commandStacks.AddSafe(commandObject); i = commandExitIndex; continue; } } } catch (Exception e1) { #if DEBUG // Helps track down parsing bugs System.Diagnostics.Debugger.Break(); #endif } } int fixedSurfaceIndex; if (surfaceIndex == -1 || surface == null) { fixedSurfaceIndex = -1; } else { fixedSurfaceIndex = i + surfaceIndex < surface.Count ? i + surfaceIndex : -1; } ColoredGlyphEffect newGlyph; if (fixedSurfaceIndex != -1) { newGlyph = new ColoredGlyphEffect(); surface[i + surfaceIndex].CopyAppearanceTo(newGlyph); newGlyph.Glyph = value[i]; } else { newGlyph = new ColoredGlyphEffect() { Glyph = value[i] }; } // Foreground if (commandStacks.Foreground.Count != 0) { commandStacks.Foreground.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks); } // Background if (commandStacks.Background.Count != 0) { commandStacks.Background.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks); } // Glyph if (commandStacks.Glyph.Count != 0) { commandStacks.Glyph.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks); } // Mirror if (commandStacks.Mirror.Count != 0) { commandStacks.Mirror.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks); } // Effect if (commandStacks.Effect.Count != 0) { commandStacks.Effect.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks); } glyphs.Add(newGlyph); } return(new ColoredString(glyphs.ToArray()) { IgnoreEffect = !commandStacks.TurnOnEffects }); }
/// <summary> /// Builds a glyph. /// </summary> /// <param name="glyphState">The current glyph being built.</param> /// <param name="glyphString">The current string of glyphs that has been processed until now.</param> /// <param name="surfaceIndex">Where on the surface this flyph will appear.</param> /// <param name="surface">The surface associated with the glyph.</param> /// <param name="stringIndex">Where in the original string this glyph is from.</param> /// <param name="processedString">The entire string being processed.</param> /// <param name="commandStack">The state of commands.</param> public abstract void Build(ref ColoredString.ColoredGlyphEffect glyphState, ColoredString.ColoredGlyphEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, string processedString, ParseCommandStacks commandStack);
/// <summary> /// Creates a new effects manager associated with a text surface. /// </summary> /// <param name="surface">Text surface to manage.</param> public EffectsManager(ICellSurface surface) { _effects = new Dictionary <ICellEffect, ColoredGlyphEffectData>(20); _effectCells = new Dictionary <int, ColoredGlyphEffectData>(50); _backingSurface = surface; }
/// <summary> /// Converts a texture's pixels to the specified <see cref="ICellSurface"/>. /// </summary> /// <param name="image">The texture to process.</param> /// <param name="surface">The surface to draw on.</param> /// <param name="cachedColorArray">A buffer holding the color information from the texture.</param> /// <param name="font">The font used with the cell surface.</param> /// <param name="fontSize">The size of the font.</param> /// <param name="blockMode"><see langword="true"/> to indicate the result should use block characters instead of text characters.</param> public static void ToSurface(this Texture2D image, ICellSurface surface, Color[] cachedColorArray, IFont font, SadRogue.Primitives.Point fontSize, bool blockMode = false) { int imageWidth = image.Width; int imageHeight = image.Height; image.GetData <Color>(cachedColorArray); surface.Clear(); global::System.Threading.Tasks.Parallel.For(0, imageHeight / fontSize.Y, (h) => //for (int h = 0; h < imageHeight / fontSize.Y; h++) { int startY = (h * fontSize.Y); //System.Threading.Tasks.Parallel.For(0, imageWidth / fontSize.X, (w) => for (int w = 0; w < imageWidth / fontSize.X; w++) { int startX = (w * fontSize.X); float allR = 0; float allG = 0; float allB = 0; for (int y = 0; y < fontSize.Y; y++) { for (int x = 0; x < fontSize.X; x++) { int cY = y + startY; int cX = x + startX; Color color = cachedColorArray[cY * imageWidth + cX]; allR += color.R; allG += color.G; allB += color.B; } } byte sr = (byte)(allR / (fontSize.X * fontSize.Y)); byte sg = (byte)(allG / (fontSize.X * fontSize.Y)); byte sb = (byte)(allB / (fontSize.X * fontSize.Y)); var newColor = new SadRogue.Primitives.Color(sr, sg, sb); float sbri = newColor.GetBrightness() * 255; if (blockMode) { if (sbri > 204) { surface.SetGlyph(w, h, 219, newColor); //█ } else if (sbri > 152) { surface.SetGlyph(w, h, 178, newColor); //▓ } else if (sbri > 100) { surface.SetGlyph(w, h, 177, newColor); //▒ } else if (sbri > 48) { surface.SetGlyph(w, h, 176, newColor); //░ } } else { if (sbri > 230) { surface.SetGlyph(w, h, '#', newColor); } else if (sbri > 207) { surface.SetGlyph(w, h, '&', newColor); } else if (sbri > 184) { surface.SetGlyph(w, h, '$', newColor); } else if (sbri > 161) { surface.SetGlyph(w, h, 'X', newColor); } else if (sbri > 138) { surface.SetGlyph(w, h, 'x', newColor); } else if (sbri > 115) { surface.SetGlyph(w, h, '=', newColor); } else if (sbri > 92) { surface.SetGlyph(w, h, '+', newColor); } else if (sbri > 69) { surface.SetGlyph(w, h, ';', newColor); } else if (sbri > 46) { surface.SetGlyph(w, h, ':', newColor); } else if (sbri > 23) { surface.SetGlyph(w, h, '.', newColor); } } } } ); }
public ICellSurface ToSurface(TextureConvertMode mode, int surfaceWidth, int surfaceHeight, TextureConvertBackgroundStyle backgroundStyle = TextureConvertBackgroundStyle.Pixel, TextureConvertForegroundStyle foregroundStyle = TextureConvertForegroundStyle.Block, Color[] cachedColorArray = null, ICellSurface cachedSurface = null) => throw new NotImplementedException();
/// <summary> /// Creates a new instance of this command. /// </summary> /// <param name="parameters">The string to parse for parameters.</param> /// <param name="glyphString">The string that has been processed so far.</param> /// <param name="commandStack">The current commands for the string.</param> /// <param name="surface">The surface hosting the string.</param> public ParseCommandBlink(string parameters, ColoredGlyph[] glyphString, ParseCommandStacks commandStack, ICellSurface surface) { string[] parametersArray = parameters.Split(':'); if (parametersArray.Length == 2) { Speed = double.Parse(parametersArray[1], CultureInfo.InvariantCulture); } if (parametersArray.Length >= 1 && parametersArray[0] != "") { _counter = int.Parse(parametersArray[0], CultureInfo.InvariantCulture); } else { _counter = -1; } // Try sync with surface editor if (surface != null) { IEnumerable <Effects.ICellEffect> effects = surface.Effects.GetEffects(); if (effects != null) { var existingBlinks = new List <Effects.ICellEffect>(effects); foreach (Effects.ICellEffect item in existingBlinks) { if (item is CustomBlinkEffect) { if (Speed == ((CustomBlinkEffect)item).BlinkSpeed) { _blinkEffect = (CustomBlinkEffect)item; } break; } } } } // Failed, look within this parse for existing if (_blinkEffect == null) { foreach (ColoredString.ColoredGlyphEffect item in glyphString) { if (item.Effect != null && item.Effect is CustomBlinkEffect) { if (Speed == ((CustomBlinkEffect)item.Effect).BlinkSpeed) { _blinkEffect = (CustomBlinkEffect)item.Effect; } } } } if (_blinkEffect == null) { _blinkEffect = new CustomBlinkEffect() { BlinkSpeed = Speed } } ; commandStack.TurnOnEffects = true; // No exceptions, set the type CommandType = CommandTypes.Effect; }
/// <inheritdoc /> public ICellSurface ToSurface(TextureConvertMode mode, int surfaceWidth, int surfaceHeight, TextureConvertBackgroundStyle backgroundStyle = TextureConvertBackgroundStyle.Pixel, TextureConvertForegroundStyle foregroundStyle = TextureConvertForegroundStyle.Block, Color[] cachedColorArray = null, ICellSurface cachedSurface = null) { if (surfaceWidth <= 0 || surfaceHeight <= 0 || surfaceWidth > _texture.Size.X || surfaceHeight > _texture.Size.Y) { throw new ArgumentOutOfRangeException("The size of the surface must be equal to or smaller than the texture."); } ICellSurface surface = cachedSurface ?? new CellSurface(surfaceWidth, surfaceHeight); // Background mode with simple resizing. if (mode == TextureConvertMode.Background && backgroundStyle == TextureConvertBackgroundStyle.Pixel) { using var resizer = GetResizedTexture(surface.Width, surface.Height); var colors = new Color[(int)resizer.Size.X * (int)resizer.Size.Y]; using Image image = resizer.Texture.CopyToImage(); byte[] imagePixels = image.Pixels; int colorIndex = 0; for (int i = 0; i < imagePixels.Length; i += 4) { surface[colorIndex++].Background = new Color(imagePixels[i], imagePixels[i + 1], imagePixels[i + 2], imagePixels[i + 3]); } return(surface); } // Calculating color based on surrounding pixels Color[] pixels = GetPixels(); int fontSizeX = (int)_texture.Size.X / surfaceWidth; int fontSizeY = (int)_texture.Size.Y / surfaceHeight; global::System.Threading.Tasks.Parallel.For(0, (int)_texture.Size.Y / fontSizeY, (h) => //for (int h = 0; h < imageHeight / fontSizeY; h++) { int startY = h * fontSizeY; //System.Threading.Tasks.Parallel.For(0, imageWidth / fontSizeX, (w) => for (int w = 0; w < _texture.Size.X / fontSizeX; w++) { int startX = w * fontSizeX; float allR = 0; float allG = 0; float allB = 0; for (int y = 0; y < fontSizeY; y++) { for (int x = 0; x < fontSizeX; x++) { int cY = y + startY; int cX = x + startX; Color color = pixels[cY * _texture.Size.X + cX]; allR += color.R; allG += color.G; allB += color.B; } } byte sr = (byte)(allR / (fontSizeX * fontSizeY)); byte sg = (byte)(allG / (fontSizeX * fontSizeY)); byte sb = (byte)(allB / (fontSizeX * fontSizeY)); var newColor = new SadRogue.Primitives.Color(sr, sg, sb); if (mode == TextureConvertMode.Background) { surface.SetBackground(w, h, newColor); } else if (foregroundStyle == TextureConvertForegroundStyle.Block) { float sbri = newColor.GetBrightness() * 255; if (sbri > 204) { surface.SetGlyph(w, h, 219, newColor); //█ } else if (sbri > 152) { surface.SetGlyph(w, h, 178, newColor); //▓ } else if (sbri > 100) { surface.SetGlyph(w, h, 177, newColor); //▒ } else if (sbri > 48) { surface.SetGlyph(w, h, 176, newColor); //░ } } else //else if (foregroundStyle == TextureConvertForegroundStyle.AsciiSymbol) { float sbri = newColor.GetBrightness() * 255; if (sbri > 230) { surface.SetGlyph(w, h, '#', newColor); } else if (sbri > 207) { surface.SetGlyph(w, h, '&', newColor); } else if (sbri > 184) { surface.SetGlyph(w, h, '$', newColor); } else if (sbri > 161) { surface.SetGlyph(w, h, 'X', newColor); } else if (sbri > 138) { surface.SetGlyph(w, h, 'x', newColor); } else if (sbri > 115) { surface.SetGlyph(w, h, '=', newColor); } else if (sbri > 92) { surface.SetGlyph(w, h, '+', newColor); } else if (sbri > 69) { surface.SetGlyph(w, h, ';', newColor); } else if (sbri > 46) { surface.SetGlyph(w, h, ':', newColor); } else if (sbri > 23) { surface.SetGlyph(w, h, '.', newColor); } } } } ); return(surface); }
/// <summary> /// Creates a new console using the existing surface. /// </summary> /// <param name="surface">The surface.</param> /// <param name="font">The font to use with the surface.</param> /// <param name="fontSize">The font size.</param> public ControlsConsole(ICellSurface surface, IFont font = null, Point?fontSize = null) : base(surface, font, fontSize) { Controls = new ControlHost(); SadComponents.Add(Controls); }
public MessageLogConsole(ICellSurface surface, IFont font = null, Point?fontSize = null) : base(surface, font, fontSize) { Initialize(); }
public TextField(Point position, int width, ICellSurface surface) => (Position, Width, _surface) = (position, width, surface);
/// <inheritdoc /> public override void Build(ref ColoredString.ColoredGlyphEffect glyphState, ColoredString.ColoredGlyphEffect[] glyphString, int surfaceIndex, ICellSurface surface, ref int stringIndex, string processedString, ParseCommandStacks commandStack) { byte r = 0; byte g = 0; byte b = 0; byte a = 0; if (Default) { if (CommandType == CommandTypes.Background) { (surface != null ? surface.DefaultBackground : Color.Transparent).Deconstruct(out r, out g, out b, out a); } else { (surface != null ? surface.DefaultForeground : Color.White).Deconstruct(out r, out g, out b, out a); } } else { if (CommandType == CommandTypes.Background) { glyphState.Background.Deconstruct(out r, out g, out b, out a); } else { glyphState.Foreground.Deconstruct(out r, out g, out b, out a); } if (!KeepRed) { r = R; } if (!KeepGreen) { g = G; } if (!KeepBlue) { b = B; } if (!KeepAlpha) { a = A; } } if (CommandType == CommandTypes.Background) { glyphState.Background = new Color(r, g, b, a); } else { glyphState.Foreground = new Color(r, g, b, a); } if (_counter != -1) { _counter--; if (_counter == 0) { commandStack.RemoveSafe(this); } } }