/// <summary> /// 色定義を読む /// </summary> /// <param name="xpm">xpm</param> /// <param name="s">ぉ</param> /// <returns></returns> private bool ParseColors(Xpm xpm, string s) { var c = 総天然色.Parse(xpm, s); xpm.AddColor(c); return(true); }
/// <summary> /// ピクセルデターを読む /// </summary> /// <param name="xpm">xpm</param> /// <param name="row">現在の行</param> /// <param name="s">ぉ</param> /// <returns></returns> private bool ParsePixels(Xpm xpm, int row, string s) { int x = 0; for (int i = 0; i < xpm.Columns * xpm.CharsPerPixel; i += xpm.CharsPerPixel, x++) { xpm.SetPixel(x, row, s.Substring(i, xpm.CharsPerPixel)); } return(true); }
/// <summary> /// 先頭行を読む /// </summary> /// <param name="xpm">xpm</param> /// <param name="s">ぉ</param> /// <returns></returns> private bool ParseStartLine(Xpm xpm, string s) { var p = s.IndexOf('*'); if (p < 0) { return(false); } s = s.Substring(p).Trim(); s = s.Substring(1, s.IndexOf('[') - 1).Trim(); xpm.Name = s; return(true); }
/// <summary> /// VALUESを読む /// </summary> /// <param name="xpm">xpm</param> /// <param name="s">ぉ</param> /// <returns></returns> private bool ParseValues(Xpm xpm, string s) { var vs = s.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (vs.Length < (int)Xpm.VulkanIndex.XHotSpot) { throw new およよ($"Values {vs.Length} < {(int)Xpm.VulkanIndex.XHotSpot}"); } for (int i = 0; i < vs.Length; ++i) { xpm.Values[i] = Int32.Parse(vs[i]); } xpm.AllocPixels(); return(true); }
/// <summary> /// ぉからXPMを生成 /// </summary> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="pixels">ピクセルデター</param> /// <returns>XPM</returns> public static Xpm Fromぉ(int width, int height, ぉ [] pixels) { var xpm = new Xpm(); xpm.Rows = height; xpm.Columns = width; xpm.AllocPixels(); int cpp = 0; foreach (var c in GenerateColorMap(pixels, out cpp).Values) { xpm.AddColor(c); } xpm.NumColors = xpm.ColorTable.Count; xpm.CharsPerPixel = cpp; // 逆引きテーブルを作っとく var rt = new Dictionary <ぉ, string>(); foreach (var c in xpm.ColorTable.Keys) { var s = xpm.ColorTable[c]; var o = s.Toぉ(); if (null == o) { throw new およよ($"色解決失敗: {s.ToColorString()}"); } if (!rt.ContainsKey(o)) { rt.Add(o, c); } } int pos = 0; for (int y = 0; y < xpm.Rows; ++y) { for (int x = 0; x < xpm.Columns; ++x) { xpm.SetPixel(x, y, rt[pixels[pos]]); pos++; } } return(xpm); }
/// <summary> /// XPMの色定義から総天然色のインスタンスを作る /// </summary> /// <param name="xpm">XPM</param> /// <param name="src">色定義</param> /// <returns>総天然色</returns> public static 総天然色 Parse(Xpm xpm, string src) { var r = new 総天然色(xpm.ColorResolver); // CPP分 r.Char = src.Substring(0, xpm.CharsPerPixel); var vs = src.Substring(xpm.CharsPerPixel + 1).Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); r.colors = new ColorRef[vs.Length / 2]; for (int i = 0, j = 0; i < vs.Length; i += 2, j++) { r.colors[j] = ParseColorRef(xpm.ColorResolver, vs[i], vs[i + 1]); if (r.colors[j].Converted) { r.ConvertedIndex = j; } } return(r); }
public void Write(System.IO.Stream stream, Xpm xpm) { StringBuilder sb = new StringBuilder(); sb.Append("/* XPM */\n") .Append($"static const char* {xpm.Name}[] = {{\n"); if (xpm.XHotSpot > 0 && xpm.YHotSpot > 0) { sb.Append("/* columns rows colors chars-per-pixel x-hotspot y-hotspot */\n") .Append($"\"{xpm.Columns} {xpm.Rows} {xpm.NumColors} {xpm.CharsPerPixel} {xpm.XHotSpot} {xpm.YHotSpot}\",\n"); } else { sb.Append("/* columns rows colors chars-per-pixel */\n") .Append($"\"{xpm.Columns} {xpm.Rows} {xpm.NumColors} {xpm.CharsPerPixel}\",\n"); } foreach (var c in xpm.ColorLookupTable) { sb.Append($"\"{c.ToColorString()}\",\n"); } sb.Append("/* pixels */\n"); // 逆引きテーブルを作っとく var rt = new Dictionary <ぉ, string>(); foreach (var c in xpm.ColorTable.Keys) { var s = xpm.ColorTable[c]; var o = s.Toぉ(); if (null == o) { throw new およよ($"色解決失敗: {s.ToColorString()}"); } if (!rt.ContainsKey(o)) { rt.Add(o, c); } } int pos = 0; var pix = xpm.Toぉ(); for (int y = 0; y < xpm.Rows; ++y) { sb.Append("\""); for (int x = 0; x < xpm.Columns; ++x) { var ck = rt[pix[pos]]; sb.Append(ck); pos++; } sb.Append("\""); if (y < xpm.Rows - 1) { sb.Append(","); } else { sb.Append("}"); } sb.Append("\n"); } var b = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); stream.Write(b, 0, b.Length); }
/// <summary> /// 文字列から読み込む /// </summary> /// <param name="source"></param> /// <returns></returns> public Xpm Load(IEnumerable <string> source) { var xpm = new Xpm(); xpm.ColorResolver = ColorResolver; var state = STATE.None; var stack = new Stack <STATE>(); int colors = 0; int pixels = 0; bool eof = false; foreach (var _s in source) { var line = _s.TrimStart(); if (line.EndsWith("};")) { eof = true; } if (!line.StartsWith("\"")) { if (line.IndexOf("/*") >= 0) { stack.Push(state); state = STATE.Comment; } if ((state == STATE.Comment) && (line.IndexOf("*/") >= 0)) { state = stack.Pop(); continue; } } if (state == STATE.Comment) { continue; } if (line.StartsWith("\"")) { line = line.Substring(line.IndexOf('\"') + 1); line = line.Substring(0, line.IndexOf('\"')); } if (line.Length == 0) { continue; } switch (state) { case STATE.None: if (START_LINE.IsMatch(line)) { if (!ParseStartLine(xpm, line)) { continue; } state = STATE.Values; } continue; case STATE.Values: ParseValues(xpm, line); state = STATE.Colors; break; case STATE.Colors: ParseColors(xpm, line); if (++colors >= xpm.NumColors) { state = STATE.Pixels; break; } break; case STATE.Pixels: ParsePixels(xpm, pixels, line); if (++pixels >= xpm.Rows) { state = STATE.Extensions; break; } break; case STATE.Extensions: // わからん break; default: if (eof) { break; } throw new およよ("ありえない"); } if (eof) { break; } } if (state == STATE.None) { throw new それちがう($"XPMじゃないっぽい"); } if (state != STATE.Extensions) { throw new およよ($"STATEが {state} で終わった"); } return(xpm); }