From 4f35ce3f69d0ef225e4e09459f7f7ae50534b413 Mon Sep 17 00:00:00 2001 From: Rich Date: Sat, 1 May 2010 10:22:31 +0000 Subject: [PATCH] Code to convert VE-PROMS\Format "RTF" files to SVG. These "RTF" files are not Rich Text Format. They are bang files containing the GenMac Macros. --- PROMS/fmtxml/RtfToSvg.cs | 336 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 PROMS/fmtxml/RtfToSvg.cs diff --git a/PROMS/fmtxml/RtfToSvg.cs b/PROMS/fmtxml/RtfToSvg.cs new file mode 100644 index 00000000..0f1830a0 --- /dev/null +++ b/PROMS/fmtxml/RtfToSvg.cs @@ -0,0 +1,336 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Text.RegularExpressions; +using System.Drawing; +using System.Xml; + +namespace fmtxml +{ + public class RtfToSvg + { + public RtfToSvg(string rtfFileName) + { + RtfFileName = rtfFileName; + } + public RtfToSvg(FileInfo rtfFile) + { + RtfFile = rtfFile; + } + private bool? _IsGenMac; + public bool IsGenMac + { + get + { + if (_IsGenMac == null) + Convert(); + return (bool)_IsGenMac; + } + set { _IsGenMac = value; } + } + private string _RtfFileName; + public string RtfFileName + { + get { return _RtfFileName; } + set + { + _RtfFileName = value; + _RtfFile = new FileInfo(_RtfFileName); + } + } + private FileInfo _RtfFile; + public FileInfo RtfFile + { + get { return _RtfFile; } + set + { + _RtfFile = value; + _RtfFileName = _RtfFile.FullName; + } + } + private string _Svg; + public string Svg + { + get + { + if (_Svg == null) + Convert(); + return _Svg; + } + } + private string Convert() + { + string buff = LoadFile(RtfFile);// Load Text + _Svg = CreateSvg(RtfFile, buff);// Convert to SVG + return _Svg; + } + /// + /// Load the file into a string by bytes + /// + /// + /// + private static string LoadFile(FileInfo file) + { + byte[] bytes = new byte[file.Length]; + using (FileStream fs = file.OpenRead()) + { + fs.Read(bytes, 0, (int)file.Length); + fs.Close(); + } + StringBuilder sb = new StringBuilder(); + foreach (byte byt in bytes) + sb.Append((char)byt); + return sb.ToString(); + } + private const string _TripleBang = "\xAD\xAD\xAD\xA8\xA8"; + Regex regLines = new Regex(@"([^\r\n]*)?\r?\n", RegexOptions.Singleline); + private string CreateSvg(FileInfo file, string buff) + { + IsGenMac = (buff.Substring(0, 5) == _TripleBang); + if(!IsGenMac) + return null; + StringBuilder sb = new StringBuilder(); + MatchCollection lines = regLines.Matches(buff); + bool svg = false; + bool group = false; + bool hasC0 = false; + foreach (Match line in lines) + { + string text = line.Groups[1].Value; + if (text == _TripleBang) + if (!svg) + svg = AddSvgPrefix(file, sb, svg); + else + AddSvgSuffix(sb, hasC0); + else if (text.StartsWith("\xAD\xAD")) + hasC0 |= AddGroupStart(sb, ref group, text).ToLower() == "c0"; + else if (text == "END") + group = AndGroupEnd(sb, group); + else if (text != "") + ProcessCommand(sb, text, file); + } + return sb.ToString(); + } + private static void AddSvgSuffix(StringBuilder sb, bool hasC0) + { + if (!hasC0) + { + AddC0(sb); + } + sb.Append(string.Format("\r\n")); + } + private static bool AndGroupEnd(StringBuilder sb, bool group) + { + if (group) sb.Append(" \r\n"); + group = false; + return group; + } + private static string AddGroupStart(StringBuilder sb, ref bool group, string text) + { + AndGroupEnd(sb, group); + group = true; + string grpID = text.Substring(2).ToUpper(); + sb.Append(string.Format(" \r\n", grpID)); + return grpID; + } + private static void AddC0(StringBuilder sb) + { + sb.Append(" \r\n"); + sb.Append(" \r\n"); + sb.Append(" \r\n"); + } + private static bool AddSvgPrefix(FileInfo file, StringBuilder sb, bool svg) + { + sb.Append("\r\n"); + sb.Append("\r\n"); + sb.Append(string.Format(" {0}\r\n", file.Name.ToLower().Replace(".rtf", ""))); + svg = true; + return svg; + } + private static Regex regCommand = new Regex(@"^[A-Z][^ \r\n]*", RegexOptions.Multiline); + private static void ProcessCommand(StringBuilder sb, string text, FileInfo file) + { + Match commandMatch = regCommand.Match(text); + ECommand command = (ECommand)Enum.Parse(typeof(ECommand), commandMatch.Value); + Converters[(int)command](sb, text); + } + private enum ECommand : int + { + LINE, + BOX, + ELLIPSE, + TEXT, + BITMAP, + GDIADJ, + RTFADJ, + ABSOLUTE + } + private delegate void Converter(StringBuilder sb, string text); + private static Converter[] _Converters; + private static Converter[] Converters + { + get + { + if (_Converters == null) + SetupConverters(); + return RtfToSvg._Converters; + } + set { _Converters = value; } + } + private static void SetupConverters() + { + Converters = new Converter[Enum.GetNames(typeof(ECommand)).Length]; + Converters[(int)ECommand.LINE] = new Converter(AddLine); + Converters[(int)ECommand.BOX] = new Converter(AddRect); + Converters[(int)ECommand.ELLIPSE] = new Converter(AddEllipse); + Converters[(int)ECommand.TEXT] = new Converter(AddText); + Converters[(int)ECommand.BITMAP] = new Converter(AddImage); + Converters[(int)ECommand.GDIADJ] = new Converter(AddGdiAdj); + Converters[(int)ECommand.RTFADJ] = new Converter(AddRtfAdj); + Converters[(int)ECommand.ABSOLUTE] = new Converter(AddAbsolute); + } + private static void AddGdiAdj(StringBuilder sb, string text) + { + // May need to do something with this + } + private static void AddAbsolute(StringBuilder sb, string text) + { + // May need to do something with this + } + private static void AddRtfAdj(StringBuilder sb, string text) + { + // Not needed + } + private static Regex regBitmap = new Regex(@"BITMAP ([-0-9]*) ([-0-9]*) (.*)$", RegexOptions.Multiline); + private static void AddImage(StringBuilder sb, string text) + { + Match bitmapMatch = regBitmap.Match(text); + //string bmFileName = FixXmlText(bitmapMatch.Groups[3].Value); + string bmFileName = FixFileName(bitmapMatch.Groups[3].Value); + Bitmap bmp = new Bitmap(bmFileName); + string bmWidth = bmp.Width.ToString() + "px"; + string bmHeight = bmp.Height.ToString() + "px"; + //Console.WriteLine("'{0}'", bmFileName); + sb.Append(string.Format(" \r\n", + TwipsToPoints(bitmapMatch.Groups[1].Value), + TwipsToPoints(bitmapMatch.Groups[2].Value), + bmWidth, + bmHeight, + bmFileName)); + } + private static Regex regText = new Regex(@"TEXT ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ""([^""]*)""", RegexOptions.Multiline); + private static void AddText(StringBuilder sb, string text) + { + Match textMatch = regText.Match(text); + //if (!_FontStyles.Contains(textMatch.Groups[5].Value)) + //{ + // Console.WriteLine("{0} - {1}", textMatch.Groups[5].Value, file.Name); + // _FontStyles.Add(textMatch.Groups[5].Value); + //} + sb.Append(string.Format(" {5}\r\n", + TwipsToPoints(textMatch.Groups[1].Value), + TwipsToPoints(textMatch.Groups[2].Value), + FontSizeToPoints(textMatch.Groups[3].Value), + FontToFamily(textMatch.Groups[4].Value), + FontStyle(textMatch.Groups[5].Value), + FixXmlText(textMatch.Groups[6].Value))); + } + private static Regex regEllipse = new Regex(@"ELLIPSE ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*)", RegexOptions.Multiline); + private static void AddEllipse(StringBuilder sb, string text) + { + Match ellipseMatch = regEllipse.Match(text); + sb.Append(string.Format(" \r\n", + TwipsToPoints(ellipseMatch.Groups[1].Value), + TwipsToPoints(ellipseMatch.Groups[2].Value), + TwipsToPoints(ellipseMatch.Groups[3].Value), + TwipsToPoints(ellipseMatch.Groups[4].Value), + TwipsToPoints(ellipseMatch.Groups[5].Value))); + } + private static Regex regBox = new Regex(@"BOX ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*)", RegexOptions.Multiline); + private static void AddRect(StringBuilder sb, string text) + { + Match boxMatch = regBox.Match(text); + sb.Append(string.Format(" \r\n", + TwipsToPoints(boxMatch.Groups[1].Value), + TwipsToPoints(boxMatch.Groups[2].Value), + TwipsToPoints(boxMatch.Groups[3].Value), + TwipsToPoints(boxMatch.Groups[4].Value), + TwipsToPoints(boxMatch.Groups[5].Value))); + } + private static Regex regLine = new Regex(@"LINE ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*) ([-0-9]*)", RegexOptions.Multiline); + private static void AddLine(StringBuilder sb, string text) + { + Match lineMatch = regLine.Match(text); + sb.Append(string.Format(" \r\n", + TwipsToPoints(lineMatch.Groups[1].Value), + TwipsToPoints(lineMatch.Groups[2].Value), + TwipsToPoints(lineMatch.Groups[3].Value) + TwipsToPoints(lineMatch.Groups[1].Value), + TwipsToPoints(lineMatch.Groups[4].Value) + TwipsToPoints(lineMatch.Groups[2].Value), + TwipsToPoints(lineMatch.Groups[5].Value))); + } + private static string FontStyle(string style) + { + StringBuilder sb = new StringBuilder(); + int iStyle = int.Parse(style); + if ((iStyle & 1) == 1) + sb.Append("font-weight=\"bold\" "); + if ((iStyle & 2) == 2) + sb.Append("text-decoration=\"underline\" "); + if ((iStyle & 4) == 4) + sb.Append("font-style=\"italic\" "); + return sb.ToString(); + } + private static string FixFileName(string fileName) + { + return Regex.Replace(fileName, @"^.*FORMAT\\", @"E:\VE-PROMS\FORMAT\"); + } + private static string FixXmlText(string str) + { + str = str.Replace("&", "&"); + str = str.Replace("'", "'"); + str = str.Replace("\"", """); + str = str.Replace("<", "<"); + str = str.Replace(">", ">"); + str = str.Replace("\x0B", " "); + return str; + } + private static string[] FontChoice = + { + "Times New Roman", + "VESymb XXXXXX", + "VolianDraw XXXXXX", + "Prestige Elite Tall", + "Courier New", + "Arial", + "Letter Gothic", + "Times New Roman", + "Letter Gothic Tall", + "Letter Gothic Tall", + "Gothic Ultra", + "VolianScript" + }; + private static float TwipsToPoints(string twips) + { + return float.Parse(twips) / 20; + } + private static float FontSizeToPoints(string fontSize) + { + return float.Parse(fontSize) / 2; + } + private static string FontToFamily(string fontID) + { + if (int.Parse(fontID) >= FontChoice.Length) + return "Font-" + fontID; + return FontChoice[int.Parse(fontID)]; + } + public void Save(string svgFileName) + { + FileInfo outFile = new FileInfo(svgFileName); + if (outFile.Exists) outFile.Delete(); + XmlDocument xDoc = new XmlDocument(); + xDoc.LoadXml(Svg); + xDoc.Save(outFile.FullName); + } + } +}