/// <summary> /// Formats the specified text element. /// </summary> /// <param name="element">The element</param> /// <param name="sb">The string buffer.</param> /// <returns></returns> private static void FormatTextElement(XElement element, ref Utf16ValueStringBuilder sb) { if (element == null) { return; } var lastNode = element.LastNode; var currentNode = element.FirstNode; while (true) { if (currentNode == null) { break; } sb.Append(FormatString(currentNode.ToString())); if (currentNode == lastNode) { break; } currentNode = currentNode.NextNode; } }
public void DrawString(Font font, ref Utf16ValueStringBuilder text, Vector2 location, Color color, float scale = 1.0f) { int cursorX = (int)location.X; // location.Y += font.Height; var textSpan = text.AsSpan(); // ReSharper disable once ForCanBeConvertedToForeach for (int i = 0; i < text.Length; i++) { if (!font.Characters.TryGetValue(textSpan[i], out var fontCharacter)) { continue; } int x = (int)(cursorX + (fontCharacter.Bearing.X * scale)); int y = (int)(location.Y - (fontCharacter.Bearing.Y * scale)); cursorX += (int)((fontCharacter.Advance >> 6) * scale); if (fontCharacter.Visible) { Draw(font.FontAtlas, new Rectangle(x, y, (int)(fontCharacter.Bounds.Width * scale), (int)(fontCharacter.Bounds.Height * scale)), fontCharacter.Bounds, color); } } }
/// <summary> /// Loads and pre-processes a shader source file. /// </summary> /// <param name="assetManager">The AssetManager to be used to resolve the asset paths.</param> /// <param name="shaderPath">The path of the shader source file.</param> /// <param name="shaderIncludePaths">The resulting list of included file paths referenced by the shader.</param> public static string Process(AssetManager assetManager, string shaderPath, out List <string> shaderIncludePaths) { // Uses ZString as a StringBuilder alternative to reduce heap allocations. // Uses ReadOnlyMemory<char> instead of string where possible for slightly better performance. // TODO: This needs more testing with larger asset libraries down the road. // System.Text.StringBuilder is slightly faster in my testing, but uses a lot more heap allocations. // If the time difference is non-negligible for larger asset files, it may be beneficial to switch back to // System.Text.StringBuilder since shaders are only pre-processed when they're loaded, so the heap // allocations aren't really an issue. Utf16ValueStringBuilder stringBuilder = ZString.CreateStringBuilder(); shaderIncludePaths = new List <string>(); PreprocessShaderSource(assetManager, ref stringBuilder, shaderPath, shaderIncludePaths = new List <string>(), new Stack <string>()); string result = stringBuilder.ToString(); return(result); }
public static Utf16ValueStringBuilder CreateStringBuilder() { var builder = new Utf16ValueStringBuilder(); builder.Init(false); return(builder); }
/// <summary> /// Converts ANSI color codes into mud color codes. Note: This updates the StringBuilder directly. /// </summary> /// <param name="sb"></param> public static void AnsiToMudColorCodes(ref Utf16ValueStringBuilder sb) { var span = sb.AsSpan(); // If there are no color codes don't bother loop through the replacements. if (!span.Contains('\x1B')) { return; } foreach (var item in ColorMap) { sb.Replace(item.AnsiColor.ToString(), item.AnsiColor.MudColorCode); } }
/// <summary> /// Converts mud color codes into ANSI color codes. Note: This updates the StringBuilder directly. /// </summary> /// <param name="sb"></param> public static void MudToAnsiColorCodes(ref Utf16ValueStringBuilder sb) { var span = sb.AsSpan(); // If there are no color codes don't bother loop through the replacements. if (!span.Contains('{')) { return; } // First the colors foreach (var item in ColorMap) { sb.Replace(item.AnsiColor.MudColorCode, item.AnsiColor.ToString()); } // Next the styles foreach (var item in StyleMap) { sb.Replace(item.AnsiColor.MudColorCode, item.AnsiColor.ToString()); } }
public ZStringWriter(IFormatProvider formatProvider) : base(formatProvider) { _sb = ZString.CreateStringBuilder(); _isOpen = true; }
/// <summary> /// Initializes a new instance /// </summary> /// <param name="disposeImmediately"> /// If true uses thread-static buffer that is faster but must return immediately. /// </param> /// <exception cref="InvalidOperationException"></exception> public ZStringBuilder(bool disposeImmediately) { _vsb = new Utf16ValueStringBuilder(disposeImmediately); }
private static void PreprocessShaderSource(AssetManager assetManager, ref Utf16ValueStringBuilder stringBuilder, string shaderPath, List <string> shaderIncludePaths, Stack <string> includeStack) { string shaderSource = GetShaderSource(assetManager, shaderPath); // Skip pre-processing if the string doesn't have any include directives. if (!shaderSource.Contains("#include ")) { stringBuilder.Append(shaderSource); return; } // Add current include path to the stack so we can book-keep to prevent circular dependencies. includeStack.Push(shaderPath); int lineNumber = 1; using var lineReader = new LineReader(shaderSource); for (ReadOnlyMemory <char> line = lineReader.ReadLine(); !lineReader.Finished; line = lineReader.ReadLine()) { // Check if the line starts with "#include " if (line.Span.StartsWith(_includeCompare.Span)) { if (TryParseIncludeLine(line, out var includeFile)) { string includePath = Path.Combine(Path.GetDirectoryName(shaderPath) ?? throw new Exception(), includeFile.ToString()); if (includeStack.Contains(includePath)) { throw new ShaderPreprocessException($"Include statement would introduce cyclic dependency: {includeFile}\n" + $"Parent: \"{shaderPath}\""); } shaderIncludePaths.Add(includePath); stringBuilder.Append("#line 1 "); stringBuilder.AppendLine((shaderIncludePaths.IndexOf(includePath) + 1).ToString()); PreprocessShaderSource(assetManager, ref stringBuilder, includePath, shaderIncludePaths, includeStack); stringBuilder.Append("\n#line "); stringBuilder.Append(lineNumber); stringBuilder.AppendLine((shaderIncludePaths.IndexOf(includePath) + 1).ToString()); } else { throw new ShaderPreprocessException($"Error when parsing include statement: {shaderPath}:{lineNumber}"); } } else { stringBuilder.Append(line); lineNumber++; } stringBuilder.Append('\n'); } includeStack.Pop(); }
public void DrawString(Font font, ref Utf16ValueStringBuilder text, Vector2 location, float scale = 1.0f) { DrawString(font, ref text, location, Color.White, scale); }
public static Utf16ValueStringBuilder CreateStringBuilder() { var builder = new Utf16ValueStringBuilder(); builder.Init(); return builder; }