Exemple #1
0
        /// <summary>
        /// Creates a <see cref="ColoredString"/> object from an existing string with the specified foreground and background, setting the ignore properties if needed.
        /// </summary>
        /// <param name="value">The current string.</param>
        /// <param name="foreground">The foreground color. If null, <see cref="ColoredString.IgnoreForeground"/> will be set.</param>
        /// <param name="background">The background color. If null, <see cref="ColoredString.IgnoreBackground"/> will be set.</param>
        /// <param name="spriteEffect">The background color. If null, <see cref="ColoredString.IgnoreEffect"/> will be set.</param>
        /// <returns>A <see cref="ColoredString"/> object instace.</returns>
        public static ColoredString CreateColored(this string value, Color?foreground = null, Color?background = null)
        {
            var stacks = new ParseCommandStacks();

            if (foreground.HasValue)
            {
                stacks.AddSafe(new ParseCommandRecolor()
                {
                    R = foreground.Value.R, G = foreground.Value.G, B = foreground.Value.B, A = foreground.Value.A, CommandType = CommandTypes.Foreground
                });
            }

            if (background.HasValue)
            {
                stacks.AddSafe(new ParseCommandRecolor()
                {
                    R = background.Value.R, G = background.Value.G, B = background.Value.B, A = background.Value.A, CommandType = CommandTypes.Background
                });
            }

            ColoredString newString = ColoredString.Parse(value, initialBehaviors: stacks);

            if (!foreground.HasValue)
            {
                newString.IgnoreForeground = true;
            }

            if (!background.HasValue)
            {
                newString.IgnoreBackground = true;
            }

            return(newString);
        }
        /// <summary>
        /// Draws the string on the console at the specified location with the specified settings.
        /// </summary>
        /// <param name="x">X location of the text.</param>
        /// <param name="y">Y location of the text.</param>
        /// <param name="text">The string to display.</param>
        /// <param name="foreground">Sets the foreground of all characters in the text.</param>
        /// <param name="background">Sets the background of all characters in the text.</param>
        /// <param name="spriteEffect">The sprite effect to set on the cell.</param>
        public void Print(int x, int y, string text, Color?foreground = null, Color?background = null)
        {
            if (String.IsNullOrEmpty(text))
            {
                return;
            }

            if (x >= textSurface.Width || x < 0 || y >= textSurface.Height || y < 0)
            {
                throw new Exception("X,Y is out of range for Print");
            }

            int index = y * textSurface.Width + x;

            if (!UsePrintProcessor)
            {
                int total     = index + text.Length > textSurface.Cells.Length ? textSurface.Cells.Length - index : index + text.Length;
                int charIndex = 0;
                for (; index < total; index++)
                {
                    textSurface.Cells[index].GlyphIndex = text[charIndex];

                    if (background.HasValue)
                    {
                        textSurface.Cells[index].Background = background.Value;
                    }
                    if (foreground.HasValue)
                    {
                        textSurface.Cells[index].Foreground = foreground.Value;
                    }

                    charIndex++;
                }
            }
            else
            {
                var stacks = new ParseCommandStacks();

                if (foreground.HasValue)
                {
                    stacks.AddSafe(new ParseCommandRecolor()
                    {
                        R = foreground.Value.R, G = foreground.Value.G, B = foreground.Value.B, A = foreground.Value.A, CommandType = CommandTypes.Foreground
                    });
                }

                if (background.HasValue)
                {
                    stacks.AddSafe(new ParseCommandRecolor()
                    {
                        R = background.Value.R, G = background.Value.G, B = background.Value.B, A = background.Value.A, CommandType = CommandTypes.Background
                    });
                }


                PrintNoCheck(index, ColoredString.Parse(text, index, textSurface, this, stacks));
            }
        }
        /// <summary>
        /// Creates a new instance of the ColoredString class with the specified string value, foreground and background colors, and a cell effect.
        /// </summary>
        /// <param name="value">The backing string.</param>
        /// <param name="foreground">The foreground color for each character.</param>
        /// <param name="background">The background color for each character.</param>
        /// <param name="spriteEffect">The sprite effects for each character.</param>
        public ColoredString(string value, Color foreground, Color background)
        {
            var stacks = new ParseCommandStacks();

            stacks.AddSafe(new ParseCommandRecolor()
            {
                R = foreground.R, G = foreground.G, B = foreground.B, A = foreground.A, CommandType = CommandTypes.Foreground
            });
            stacks.AddSafe(new ParseCommandRecolor()
            {
                R = background.R, G = background.G, B = background.B, A = background.A, CommandType = CommandTypes.Background
            });
            _characters = ColoredString.Parse(value, initialBehaviors: stacks)._characters;
        }
        /// <summary>
        /// Draws the string on the console at the specified location with the specified foreground and background color, wrapping if needed.
        /// </summary>
        /// <param name="x">X location of the text.</param>
        /// <param name="y">Y location of the text.</param>
        /// <param name="text">The string to display.</param>
        /// <param name="foreground">Sets the foreground of all characters in the text.</param>
        /// <param name="background">Sets the background of all characters in the text.</param>
        public void Print(int x, int y, string text, Color foreground, Color background)
        {
            if (String.IsNullOrEmpty(text))
            {
                return;
            }

            if (x >= textSurface.Width || x < 0 || y >= textSurface.Height || y < 0)
            {
                throw new Exception("X,Y is out of range for Print");
            }

            int index = y * textSurface.Width + x;

            if (!UsePrintProcessor)
            {
                int total     = index + text.Length > textSurface.Cells.Length ? textSurface.Cells.Length - index : index + text.Length;
                int charIndex = 0;
                for (; index < total; index++)
                {
                    textSurface.Cells[index].Glyph      = text[charIndex];
                    textSurface.Cells[index].Background = background;
                    textSurface.Cells[index].Foreground = foreground;
                    charIndex++;
                }
            }
            else
            {
                var behaviorFore = new ParseCommandRecolor()
                {
                    R = foreground.R, G = foreground.G, B = foreground.B, A = foreground.A, CommandType = CommandTypes.Foreground
                };
                var behaviorBack = new ParseCommandRecolor()
                {
                    R = background.R, G = background.G, B = background.B, A = background.A, CommandType = CommandTypes.Background
                };
                var stacks = new ParseCommandStacks();
                stacks.AddSafe(behaviorFore);
                stacks.AddSafe(behaviorBack);
                PrintNoCheck(index, ColoredString.Parse(text, index, textSurface, this, stacks));
            }
            textSurface.IsDirty = true;
        }
        /// <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></returns>
        public static ColoredString Parse(string value, int surfaceIndex = -1, CellSurface surface = null, ParseCommandStacks initialBehaviors = null)
        {
            ParseCommandStacks  commandStacks = initialBehaviors ?? new ParseCommandStacks();
            List <ColoredGlyph> glyphs        = new List <ColoredGlyph>(value.Length);

            for (int i = 0; i < value.Length; i++)
            {
                ColoredGlyph[] 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
                        throw e1;
#endif
                    }
                }

                int fixedSurfaceIndex;

                if (surfaceIndex == -1 || surface == null)
                {
                    fixedSurfaceIndex = -1;
                }
                else
                {
                    fixedSurfaceIndex = i + surfaceIndex < surface.Cells.Length ? i + surfaceIndex : -1;
                }

                ColoredGlyph newGlyph;

                if (fixedSurfaceIndex != -1)
                {
                    newGlyph = new ColoredGlyph(surface[i + surfaceIndex])
                    {
                        Glyph = value[i]
                    };
                }
                else
                {
                    newGlyph = new ColoredGlyph(new Cell())
                    {
                        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);
                }

                if (commandStacks.Glyph.Count != 0)
                {
                    commandStacks.Glyph.Peek().Build(ref newGlyph, existingGlyphs, fixedSurfaceIndex, surface, ref i, value, commandStacks);
                }

                // SpriteEffect
                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
            });
        }