private void PrintStringCore(char quoteType, bool tripleQuoted, string text) { _out.Write(quoteType, false); if (tripleQuoted) { _out.Write(quoteType, false); _out.Write(quoteType, false); char a = '\0', b = '\0'; foreach (char c in text) { if (c == quoteType && b == quoteType && a == quoteType) { _out.Write(@"\\", false); } // prevent false escape sequences if (a == '\\' && b == '\\' && (c == quoteType || c == 'n' || c == 'r' || c == '\\')) { _out.Write(@"\\", false); } _out.Write(c, false); a = b; b = c; } _out.Write(quoteType, false); _out.Write(quoteType, false); } else { _out.Write(PrintHelpers.EscapeCStyle(text, EscapeC.Control, quoteType), false); } _out.Write(quoteType, true); }
internal string LiteralTypeAsLes3Identifier() { if (Les2Printer.IsNormalIdentifier(TypeMarker)) { return(TypeMarker.Name); } else { return("`" + PrintHelpers.EscapeCStyle(TypeMarker.Name, EscapeC.Control, '`') + "`"); } }
public override string ToString() { if (Value is string) { return(LiteralTypeAsLes3Identifier() + "\"" + PrintHelpers.EscapeCStyle((string)Value, EscapeC.Control | EscapeC.DoubleQuotes) + "\""); } else if (Value is double) { return(((double)Value).ToString("0.0") + LiteralTypeAsLes3Identifier()); } else { return(Value.ToString() + LiteralTypeAsLes3Identifier()); } }
/// <summary>Prints a character as a string, e.g. <c>'a' -> "'a'"</c>, with /// the special value -1 representing EOF, so PrintChar(-1, ...) == "EOF".</summary> protected void PrintChar(int c, StringBuilder sb) { if (c == -1) { sb.Append("EOF"); } else if (c >= 0 && c < 0xFFFC) { sb.Append('\''); PrintHelpers.EscapeCStyle((char)c, sb, EscapeC.Default, '\''); sb.Append('\''); } else { sb.Append(c); } }
private static string GetStringsNotEqualMessage(string a, string b) { // TODO: test this code if (a == null || b == null) { return(GetObjectMismatchMessage(a, b)); } else { int i, c = System.Math.Min((a ?? "").Length, (b ?? "").Length); for (i = 0; i < c; i++) { if (a[i] != b[i]) { break; } } StringBuilder msg = new StringBuilder(); if (a.Length == b.Length) { msg.AppendFormat(" String lengths are both {0}. Strings differ at index {1}.\n", c, i); } else { msg.AppendFormat(" Expected string length {0} but was {1}. Strings differ at index {2}.\n", a.Length, b.Length, i); } int a_i = i, b_i = i, maxlen = System.Math.Max(a.Length, b.Length); msg.AppendFormat(" Expected: {0}\n", GetQuotedString(ref a, ref a_i, maxlen)); msg.AppendFormat(" But was: {0}\n", GetQuotedString(ref b, ref b_i, maxlen)); int TailLength = "-----------".Length; var prefix = b.Left(b_i); int i_adjusted = PrintHelpers.EscapeCStyle(prefix, EscapeC.Default, '"').Length; msg.Append(' ', 2); msg.Append('-', TailLength + i_adjusted); msg.Append("^\n"); return(msg.ToString()); } }
static string GetQuotedString(ref string s, ref int dif_i, int len) { int maxw = TruncateStringsLongerThan; if (len > maxw) { if (dif_i < maxw / 2) { s = s.Left(maxw - 3) + "..."; // "beginning..." } else if (len - dif_i < maxw / 2) { s = "..." + s.SafeSubstring(len - (maxw - 3)); // "...ending" dif_i -= len - maxw; } else { s = "..." + s.SafeSubstring(dif_i - maxw / 2 + 3, maxw - 6) + "..."; dif_i = maxw / 2; // "...middle..." } } return("\"" + PrintHelpers.EscapeCStyle(s, EscapeC.Default, '"') + "\""); }
private static void Append(StringBuilder sb, int c) { if (c < 32 || c == '\\' || c == ']') { if (c <= -1) { sb.Append(@"\$"); } else { sb.Append(PrintHelpers.EscapeCStyle(((char)c).ToString(), EscapeC.Default, ']')); } } else if (c == '-' || c == '^' && sb.Length == 1) { sb.Append('\\'); sb.Append((char)c); } else { sb.Append((char)c); } }
/// <summary>Parses a normal or triple-quoted string whose starting quotes /// have been stripped out. If triple-quote parsing was requested, stops /// parsing at three quote marks; otherwise, stops parsing at a single /// end-quote or newline.</summary> /// <returns>true if parsing stopped at one or three quote marks, or false /// if parsing stopped at the end of the input string or at a newline (in /// a string that is not triple-quoted).</returns> /// <remarks>This method recognizes LES and EC#-style string syntax.</remarks> public static bool UnescapeString(ref UString sourceText, char quoteType, bool isTripleQuoted, Action <int, string> onError, StringBuilder sb, UString indentation = default(UString), bool allowExtraIndent = false) { Debug.Assert(quoteType == '"' || quoteType == '\'' || quoteType == '`'); bool fail; for (; ;) { if (sourceText.IsEmpty) { return(false); } int i0 = sourceText.InternalStart; if (!isTripleQuoted) { EscapeC category = 0; int c = ParseHelpers.UnescapeChar(ref sourceText, ref category); if ((c == quoteType || c == '\n') && sourceText.InternalStart == i0 + 1) { return(c == quoteType); // end of string } if ((category & EscapeC.Unrecognized) != 0) { // This backslash was ignored by UnescapeChar onError(i0, @"Unrecognized escape sequence '\{0}' in string".Localized(PrintHelpers.EscapeCStyle(sourceText[0, ' '].ToString(), EscapeC.Control))); } else if ((category & EscapeC.HasInvalid6DigitEscape) != 0) { onError(i0, @"Invalid 6-digit \u code treated as 5 digits".Localized()); } sb.AppendCodePoint(c); if ((category & EscapeC.BackslashX) != 0 && c >= 0x80) { DetectUtf8(sb); } else if (c.IsInRange(0xDC00, 0xDFFF)) { RecodeSurrogate(sb); } } else { // Inside triple-quoted string int c; if (sourceText[2, '\0'] == '/') { // Detect escape sequence c = ParseHelpers.UnescapeChar(ref sourceText); if (sourceText.InternalStart > i0 + 1) { G.Verify(sourceText.PopFirst(out fail) == '/'); } } else { c = sourceText.PopFirst(out fail); if (fail) { return(false); } if (c == quoteType) { if (sourceText[0, '\0'] == quoteType && sourceText[1, '\0'] == quoteType) { sourceText = sourceText.Substring(2); // end of string return(true); } } if (c == '\r' || c == '\n') { // To ensure platform independency of source code, CR and // CR-LF become LF. if (c == '\r') { c = '\n'; var copy = sourceText.Clone(); if (sourceText.PopFirst(out fail) != '\n') { sourceText = copy; } } // Inside a triple-quoted string, the indentation following a newline // is ignored, as long as it matches the indentation of the first line. UString src = sourceText, ind = indentation; int sp; while ((sp = src.PopFirst(out fail)) == ind.PopFirst(out fail) && !fail) { sourceText = src; } if (allowExtraIndent && fail) { // Allow an additional one tab or three spaces when initial indent matches if (sp == '\t') { sourceText = src; } else if (sp == ' ') { sourceText = src; if (src.PopFirst(out fail) == ' ') { sourceText = src; } if (src.PopFirst(out fail) == ' ') { sourceText = src; } } } } } sb.AppendCodePoint(c); } } }
private (Bitmap, string, SizeF) ConvertFont(Font font, int minCh, int maxCh, Padding shave, bool autoShave, bool hexStringOutput, bool clearType, bool json, bool fourBitsPerPixel) { var outputs = new List <(string Char, float Width, List <BigInteger> CharBitmap)>(); SizeF maxSize = new SizeF(); int bmpWidth = Min(Max(maxCh - minCh + 1, 0) * MaxCharWidth, 32000); var bitmap = new Bitmap(bmpWidth, MaxCharHeight); using (var g = Graphics.FromImage(bitmap)) { g.Clear(Color.Black); int left = 0; for (int i = minCh; i <= maxCh; i++) { // Measure and draw character (char)i string c = new string((char)i, 1); g.TextRenderingHint = clearType ? TextRenderingHint.ClearTypeGridFit : fourBitsPerPixel ? TextRenderingHint.AntiAliasGridFit : TextRenderingHint.SingleBitPerPixelGridFit; var size = g.MeasureString(c, font); int fullWidth = (int)Round(size.Width); maxSize = new SizeF(Max(size.Width, maxSize.Width), Max(size.Height, maxSize.Height)); g.DrawString(c, font, Brushes.White, left, 0); // Shave off left and right based on actual pixels if (autoShave) { int shaveLeft, shaveRight; for (shaveLeft = 0; shaveLeft < shave.Left; shaveLeft++) { if (!ColumnIsEmpty(left + shaveLeft)) { break; } } for (shaveRight = 0; shaveRight < shave.Right; shaveRight++) { if (!ColumnIsEmpty(left + fullWidth - 1 - shaveRight)) { break; } } shave.Left = shaveLeft; shave.Right = shaveRight; bool ColumnIsEmpty(int x) { if (x < 0) { return(false); } for (int y = 0; y < size.Height; y++) { Color px = bitmap.GetPixel(x, y); if (((px.R + px.G * 2 + px.B) >> 9) != 0) { return(false); } } return(true); } } // Convert to a list of scanlines in 4-bit grayscale var charBitmap = new List <BigInteger>(); for (int y = 0; y < Round(size.Height); y++) { BigInteger row = 0; for (int x = shave.Left; x < fullWidth - shave.Right; x++) { Color px = bitmap.GetPixel(left + x, y); int fourBitGray = (px.R + px.G * 2 + px.B) >> 6; if (fourBitsPerPixel) { row = (row << 4) + fourBitGray; } else { row = (row << 1) + (fourBitGray >> 3); } } charBitmap.Add(row); } bitmap.SetPixel(left, (int)size.Height, Color.Red); outputs.Add((c, Max(size.Width - (shave.Left + shave.Right), 1), charBitmap)); // Advance render position left += Max(fullWidth - shave.Right, 0); } } // Shave top & bottom long mask = fourBitsPerPixel ? 0x888888888888888 : 0xFFFFFFFFFFFFFFF; for (int y = 0; y < shave.Top; y++) { if (autoShave && outputs.Any(item => (item.CharBitmap[0] & mask) != 0)) { break; } foreach (var item in outputs.Where(it => it.CharBitmap.Count > 0)) { item.CharBitmap.RemoveAt(0); } } for (int y = 0; y < shave.Bottom; y++) { if (autoShave && outputs.Any(item => (item.CharBitmap[item.CharBitmap.Count - 1] & mask) != 0)) { break; } foreach (var item in outputs.Where(it => it.CharBitmap.Count > 0)) { item.CharBitmap.RemoveAt(item.CharBitmap.Count - 1); } } var lines = new List <string>(); if (!json) { foreach (var(ch, width, charBitmap) in outputs) { int intWidth = (int)Round(width); string nums = NumberList(intWidth, charBitmap); lines.Add($"{((int)ch[0]).ToString().PadLeft(3,' ')},{intWidth.ToString().PadLeft(2)} ,{nums}, {ch}"); } } else { lines.Add("["); foreach (var(ch, width, charBitmap) in outputs) { string c = "\"" + PrintHelpers.EscapeCStyle(ch) + "\""; if (lines.Any()) { lines[lines.Count - 1] += ","; } lines.Add(@"{"); int intWidth = (int)Round(width); lines.Add($@" ""char"": {c}, ""floatWidth"": {width}, ""width"": {intWidth}, ""bits"":"); if (hexStringOutput) { lines.Add($@" ""{NumberList(intWidth, charBitmap)}"""); } else { lines.Add($" [ {NumberList(intWidth, charBitmap)} ]"); } lines.Add(@"}"); } lines.Add("]"); } return(bitmap, string.Join("\r\n", lines), maxSize); string NumberList(int intWidth, List <BigInteger> charBitmap) { if (hexStringOutput) { int rowLength = fourBitsPerPixel ? intWidth : (intWidth + 3) >> 2; return(string.Join(",", charBitmap.Select(row => row.ToString("X" + rowLength).Right(rowLength)))); } else { return(string.Join(",", charBitmap)); } } }