SourceCode/PROMS/fmtxml/GenXmlToSvg.cs
2008-08-26 13:55:41 +00:00

770 lines
20 KiB
C#

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace fmtxml
{
/// <summary>
/// Convert genmac xml files to svg. svg (Scalar Vector Graphics
/// in XML format), so that genmac can be used in the 32-bit proms
/// system. The generated files will be used by developers and
/// customer service persons to do macros.
/// </summary>
public class GenXmlToSvg
{
private string genName;
private XmlDocument xmlDoc;
private XmlDocument xmlOutDoc;
private XmlElement topOutElement;
private int Convertn = 300, I = 300, C = 118, D = 1;
private float Wid = 3;
private int RTFFontSize = 20;
private int RTFFontFamily = 3;
private 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 string [] OldName =
{
"BOX1",
"BOX2",
"BOX3",
"BOX4",
"BOX5",
"HDR1",
"HDR2",
"HDR3",
"HDR4",
"HDR5",
"BOLDX",
"CNUM",
"CHKBOX",
"CHKBOX2",
"CHKBOX3",
"CHKBOX4",
"CHKBOX5",
"CHKBOX6",
"CHKBOX7",
"CHKBOX8",
"CHKBOX9",
"CHKBOX10",
"CHKBOX11",
"CHKBOX12",
"CHKBOX13",
"CHKBOX14",
"CHKBOX15",
"CHKBOX16",
"CHKBOX17",
"PLNTPLMAC",
"PLNTPLMAC2",
"GRAPHMAC0",
"GRAPHMAC1",
"RIGHTCHECKOFF",
"HPGLCOMMAND0",
"HPGLCOMMAND1",
"HPGLCOMMAND2",
"HPGLCOMMAND3",
"HPGLCOMMAND4",
"HPGLCOMMAND5",
"HPGLCOMMAND6",
"HPGLCOMMAND7",
"HPGLCOMMAND8",
"HPGLCOMMAND9",
"LTCO",
"SECDBLBXVERT",
"BOX6",
"BOX7",
"BOX8",
"ACAS_CHECKBOX",
"ACAS_CHECKLINE",
};
private string [] NewName =
{
"B1",
"B2",
"B3",
"B4",
"B5",
"H1",
"H2",
"H3",
"H4",
"H5",
"m33",
"C0",
"C1",
"C2",
"C3",
"C4",
"C5",
"C6",
"C7",
"C8",
"C9",
"C10",
"C11",
"C12",
"C13",
"C14",
"C15",
"C16",
"C17",
"m18",
"m19",
"m20",
"m21",
"C22",
"m23",
"m24",
"m25",
"m26",
"m27",
"m28",
"m29",
"m30",
"m31",
"m32",
"m20",
"m34",
"B6",
"B7",
"B8",
"m35",
"m36",
};
private int RTFBUI = 0;
private int Sp = -1;
private float cx = 0;
private float cy = 0;
private int fidx=0;
private int [] fontfam;
private int [] fontsiz;
private float [] PPx;
private float [] PPy;
// the following define RTFBUI values
private static int BOLD = 0x01;
private static int UNDERLINE = 0x02;
private static int ITALICS = 0x04;
public GenXmlToSvg(string nm)
{
genName = nm;
try
{
fontfam = new int[20];
fontsiz = new int[20];
PPx = new float[12];
PPy = new float[12];
ReadXml();
ConvertGenXmlToDIXml();
WriteXml();
}
catch (Exception ex)
{
Console.WriteLine("Genmac.xml name = " + nm + ". Error is " + ex.Message);
}
}
private float CPoint(float x)
{
if (Convertn == C)
{
// convert from x (in centimeters) to inches & then to points
return (float) (.3937 * x * 72);
} // convert from x (in inches) to points
else if (Convertn == I)
return (float)(x * 72);
else // convert from x (in dots) to twips & then points
return (float)(((4.8 * x + 0.5)/1440f)*72);
}
private void WriteXml()
{
string path = "E:\\proms.net\\genmac.xml\\" + genName.Substring(0,genName.LastIndexOf(".")) + ".svg";
XmlTextWriter writer = new XmlTextWriter(path,System.Text.Encoding.Unicode);
writer.Formatting=System.Xml.Formatting.Indented;
xmlOutDoc.Save(writer);
}
private void ReadXml()
{
string fnm = "E:\\proms.net\\genmac.xml\\convert\\" + genName;
xmlDoc = new XmlDocument();
XmlTextReader reader = new XmlTextReader(fnm);
xmlDoc.Load(reader);
reader.Close();
}
private void ConvertGenXmlToDIXml()
{
// first create the document for the svg version of the macro files
// and add the top svg element.
xmlOutDoc = new XmlDocument();
topOutElement = xmlOutDoc.CreateElement("svg");
topOutElement.SetAttribute("width","8in");
topOutElement.SetAttribute("height","10in");
topOutElement.SetAttribute("viewBox","0 0 576 720");
// topOutNode.Attributes.Append(attr);
// topOutNode.Attributes.Append<svg width="8in" height="10in" viewBox="0 0 576 720"
// xmlns="http://www.w3.org/2000/svg" version="1.1">
xmlOutDoc.AppendChild(topOutElement);
// Next add the description node, which is the name of the plant format.
XmlElement descNode = xmlOutDoc.CreateElement("desc");
descNode.InnerText = genName.Substring(0,genName.LastIndexOf("."));
topOutElement.AppendChild(descNode);
XmlElement top = (XmlElement) xmlDoc.FirstChild;
XmlNode sv = top.SelectSingleNode("STATICVOID");
XmlNodeList xmlNds = top.SelectNodes("MACRO");
// Now for each macro, create a svg group with the name given to
// it. Later we may change this to map to what was created in 16-bit
// proms (for example BOX1 -> B1)
foreach (XmlNode nd in xmlNds)
{
XmlNode name = nd.SelectSingleNode("NAME");
XmlElement elm = (XmlElement) name;
XmlElement grp = xmlOutDoc.CreateElement("g");
string cname = GetName(name.InnerText);
grp.SetAttribute("id",cname);
topOutElement.AppendChild(grp);
XmlNode definition = nd.SelectSingleNode("DEFINITION");
try
{
string str = ProcessMacroDefinition(grp,definition,sv);
}
catch (Exception e)
{
MessageBox.Show("Error processing macro definition for " + this.genName, e.Message);
}
}
xmlNds = top.SelectNodes("USERDEF");
// Now for each user defined macro, create a svg group with the
// name given to it.
foreach (XmlNode nd in xmlNds)
{
XmlNode name = nd.SelectSingleNode("NAME");
XmlElement elm = (XmlElement) name;
XmlElement grp = xmlOutDoc.CreateElement("g");
string tmpdebug = name.InnerText.Trim("\n".ToCharArray());
grp.SetAttribute("id",tmpdebug);
topOutElement.AppendChild(grp);
XmlNode definition = nd.SelectSingleNode("DEFINITION");
try
{
string str = ProcessMacroDefinition(grp,definition,sv);
}
catch (Exception e)
{
MessageBox.Show("Error processing macro definition for " + this.genName, e.Message);
}
}
}
// convert the macro names as was done in 16-bit code?
string GetName(string oname)
{
for (int i=0; i<51 ; i++)
{
if (oname == OldName[i]) return NewName[i];
}
return "NONAME";
}
private void PushFont()
{
if( fidx < 19 )
{
fontfam[fidx] = RTFFontFamily;
fontsiz[fidx] = RTFFontSize;
fidx++;
}
return;
}
private void PopFont()
{
if( fidx > 0 )
{
fidx--;
RTFFontFamily = fontfam[fidx];
RTFFontSize = fontsiz[fidx];
}
return;
}
private void PushPos()
{
if (Sp < 11)
{
Sp++;
PPx[Sp] = cx;
PPy[Sp] = cy;
}
}
private void PopPos()
{
if (Sp > -1)
{
cx = PPx[Sp];
cy = PPy[Sp];
Sp--;
}
}
private XmlElement RTFAdjust(float x, float y)
{
// This was used for RTF export only.
return null;
}
private XmlElement GDIAdjust(float x, float y)
{
// can't quite figure out what this is doing
// KBR TODO: gdiadjust
return null;
}
private float GetOneFloat(string cmd)
{
int indxlp = cmd.IndexOf("(");
int indxrp = cmd.IndexOf(")");
string tmp = cmd.Substring(indxlp+1,indxrp-indxlp-1);
return (float) Convert.ToDouble(tmp);
}
private void GetTwoFloats(string cmd, ref float x, ref float y)
{
int indxlp = cmd.IndexOf("(");
int indxcm = cmd.IndexOf(",");
int indxrp = cmd.IndexOfAny("),".ToCharArray(),indxcm+1);
x = (float) Convert.ToDouble(cmd.Substring(indxlp+1,indxcm-indxlp-1));
y = (float) Convert.ToDouble(cmd.Substring(indxcm+1,indxrp-indxcm-1));
}
private XmlElement DefineMacro(string str)
{
byte x = Convert.ToByte(173);
cx=cy=0;
return null;
}
private XmlElement HorizontalLine(float X)
{
XmlElement box = this.xmlOutDoc.CreateElement("line");
box.SetAttribute("x1",cx.ToString());
box.SetAttribute("y1",cy.ToString());
box.SetAttribute("x2",(cx+CPoint(X)).ToString());
box.SetAttribute("y2",cy.ToString());
box.SetAttribute("stroke-width",Wid.ToString());
return box;
}
private XmlElement VerticalLine(float Y)
{
XmlElement box = this.xmlOutDoc.CreateElement("line");
box.SetAttribute("x1",cx.ToString());
box.SetAttribute("y1",cy.ToString());
box.SetAttribute("x2",cx.ToString());
box.SetAttribute("y2",(cy+CPoint(Y)).ToString());
box.SetAttribute("stroke-width",Wid.ToString());
return box;
}
private XmlElement DiagLine(float X, float Y)
{
XmlElement box = this.xmlOutDoc.CreateElement("line");
box.SetAttribute("x1",cx.ToString());
box.SetAttribute("y1",cy.ToString());
box.SetAttribute("x2",(cx+CPoint(X)).ToString());
box.SetAttribute("y2",(cy+CPoint(Y)).ToString());
box.SetAttribute("stroke-width",Wid.ToString());
return box;
}
private XmlElement Box(float X, float Y)
{
XmlElement box = this.xmlOutDoc.CreateElement("rect");
box.SetAttribute("x",cx.ToString());
box.SetAttribute("y",cy.ToString());
box.SetAttribute("width",CPoint(X).ToString());
box.SetAttribute("height",CPoint(Y).ToString());
box.SetAttribute("fill","none");
box.SetAttribute("stroke","black");
box.SetAttribute("stroke-width",Wid.ToString());
return box;
}
private XmlElement Ellipse(float X, float Y)
{
XmlElement ellipse = this.xmlOutDoc.CreateElement("ellipse");
ellipse.SetAttribute("cx",cx.ToString());
ellipse.SetAttribute("cy",cy.ToString());
ellipse.SetAttribute("rx",(CPoint(X)).ToString());
ellipse.SetAttribute("ry",(CPoint(Y)).ToString());
ellipse.SetAttribute("fill","none");
ellipse.SetAttribute("stroke","black");
ellipse.SetAttribute("stroke-width",Wid.ToString());
return ellipse;
}
private XmlElement Text(float X, float Y, string str)
{
//text-decoration="underline"
//font-weight="bold"
//font-style="italic"
XmlElement text = this.xmlOutDoc.CreateElement("text");
text.SetAttribute("x",(cx+CPoint(X)).ToString());
text.SetAttribute("y",(cy+CPoint(Y)).ToString());
text.SetAttribute("font-family",FontChoice[RTFFontFamily]);
text.SetAttribute("font-size",(RTFFontSize/2).ToString());
if ((RTFBUI&BOLD)==1) text.SetAttribute("font-weight","bold");
if ((RTFBUI&UNDERLINE)==1) text.SetAttribute("text-decoration", "underline");
if ((RTFBUI&ITALICS)==1) text.SetAttribute("font-style","italic");
text.InnerText = str;
return text;
}
private XmlElement[] RTFBox3(float x, float y)
{
XmlElement[] elearr = new XmlElement[3];
PushPos();
elearr[0] = VerticalLine(y);
cy += CPoint(y);
elearr[1] = HorizontalLine(x);
cx += CPoint(x);
float ftmp = (float) (y*-1.0);
cy += CPoint(ftmp);
elearr[2] = VerticalLine(y);
PopPos();
return elearr;
}
private XmlElement BitMap(float X, float Y, string str)
{
XmlElement bmap = xmlOutDoc.CreateElement("image");
bmap.SetAttribute("x",(cx+CPoint(X)).ToString());
bmap.SetAttribute("y",(cy+CPoint(Y)).ToString());
Bitmap bmp= new Bitmap(str);
bmap.SetAttribute("width",bmp.Width.ToString()+"px");
bmap.SetAttribute("height",bmp.Height.ToString()+"px");
//bmap.SetAttribute("xlink:href",str);
bmap.SetAttribute("bname",str);
return bmap;
}
private void GetFont(string fontexp)
{
if (fontexp==null||fontexp=="")
{
RTFFontFamily = 3;
RTFFontSize = 20;
}
else if (fontexp.IndexOf("PICA")>-1)
{
RTFFontFamily = 4;
RTFFontSize = 24;
}
else if (fontexp.IndexOf("EXPANDED")>-1)
{
RTFFontSize = 24;
}
else if(fontexp.IndexOf("SANSERIF")>-1)
{
RTFFontFamily = 6;
RTFFontSize = 20;
}
else if (fontexp.IndexOf("PROPT12")>-1)
{
RTFFontFamily = 5;
RTFFontSize = 22;
}
else if (fontexp.IndexOf("COMPRESSED")>-1)
{
RTFFontFamily = 6;
RTFFontSize = 14;
}
if (fontexp.IndexOf("BOLD")>-1) RTFBUI |= BOLD; else RTFBUI &= 0xFFFE;
if (fontexp.IndexOf("UNDERLINE")>-1) RTFBUI |= UNDERLINE; else RTFBUI &= 0xFFFD;
if (fontexp.IndexOf("ITALICS")>-1) RTFBUI |= ITALICS; else RTFBUI &= 0xFFFB;
}
private string ProcessMacroDefinition(XmlElement grp, XmlNode idef, XmlNode functions)
{
XmlElement elm = (XmlElement) idef;
string def = elm.InnerText;
StringBuilder str_result = new StringBuilder();
fidx=0;
cx = 0;
cy = 0;
Wid = 3;
RTFFontSize = 20;
RTFFontFamily = 3;
Sp = -1;
// for each element, process the token for the element and add it to the
// xml tree (ProcessToken does both).
int lindx = 0;
int indx = def.IndexOf(";");
while (indx>-1)
{
ProcessToken(grp, def, lindx, indx, functions);
lindx = indx+1;
indx = def.IndexOf(";",lindx);
}
return str_result.ToString();
}
private void ProcessToken(XmlElement grp, string def, int lindx, int indx, XmlNode functions)
{
float x=0,y=0;
XmlElement retval = null;
//get the token, i.e. from last index to this one.
string token = def.Substring(lindx,indx-lindx).Trim();
if (token==null||token=="")return;
string cmd = token; // cmd has the command without parens/values
if (token.IndexOf("(")>-1) cmd = token.Substring(0,token.IndexOf("("));
if (token.IndexOf("RTFFontSize")>-1)cmd = "RTFFontSize";
if (token.IndexOf("RTFFontFamily")>-1)cmd = "RTFFontFamily";
if (token.IndexOf("RTFBUI")>-1) cmd = "RTFBUI";
if (token.IndexOf("DEFMAC")>-1) cmd = "DEFMAC";
if (token.IndexOf("HLINE")>-1) cmd = "HLINE";
if (token.IndexOf("TEXT")>-1) cmd = "TEXT";
if (token.IndexOf("BITMAP")>-1) cmd = "BITMAP";
if (cmd==null)return;
try
{
switch (cmd)
{
case "DEFMAC": // command is DEFMAC(xyz)
MessageBox.Show("DEFMAC found, format = " + genName + " not converted - do manually");
int indxl = token.IndexOf("(");
int indxr = token.IndexOf(")");
string strx = token.Substring(indxl+1,indxr-indxl-1).Trim();
retval = DefineMacro(strx);
break;
case "PUSHF":
PushFont();
break;
case "POPF":
PopFont();
break;
case "PUSHP":
PushPos();
break;
case "POPP":
PopPos();
break;
case "UNIT":
if (token.IndexOf("C")>-1)Convertn = C;
else if (token.IndexOf("I",4)>-1)Convertn = I;
else if (token.IndexOf("D")>-1)Convertn = D;
break;
case "RTFADJ": // command is RTFADJ(x,y)
GetTwoFloats(token, ref x, ref y);
retval = RTFAdjust(x, y);
break;
case "GDIADJ": // command is GDIADJ(x,y)
GetTwoFloats(token, ref x, ref y);
retval = GDIAdjust(x, y);
break;
case "FONT": //comand is FONT(FONTSTR)
GetFont(token);
break;
case "RTFFontSize": // command is RTFFontSize = x
int indxe = token.IndexOf("=");
string numstr = token.Substring(indxe+1,token.Length-indxe-1).Trim();
if (numstr.IndexOf("*")>-1)
{
int i1 = Convert.ToInt32(numstr.Substring(0,numstr.IndexOf("*")));
int i2 = Convert.ToInt32(numstr.Substring(numstr.IndexOf("*")+1,numstr.Length-numstr.IndexOf("*")-1));
RTFFontSize = i1*i2;
}
else
RTFFontSize = Convert.ToInt32(numstr);
break;
case "RTFBUI":
// command either sets it '=' or ORs it '|= ', look for these.
int ieq = token.IndexOf("=");
string val = token.Substring(ieq+1,token.Length-ieq-1).Trim();
int amt=0;
if (token.IndexOf("0x")<0)
amt = Convert.ToInt32(val);
else
amt = Convert.ToInt32(val,16);
int operor = token.IndexOf("|=");
int operand = token.IndexOf("&=");
if (operor<0 && operand<0)
RTFBUI = amt;
else if (operor>0)
RTFBUI |= amt;
else
RTFBUI &= amt;
break;
case "RTFFontFamily": // command is RTFFontFamily = x
indxe = token.IndexOf("=");
numstr = token.Substring(indxe+1,token.Length-indxe-1).Trim();
RTFFontFamily = Convert.ToInt32(numstr);
break;
case "LNWID": // command is LNWID(w)
float w = GetOneFloat(token);
Wid = CPoint(w);
break;
case "MOVA": // command is MOVA(x, y)
GetTwoFloats(token,ref x, ref y);
cx = CPoint(x);
cy = CPoint(y);
break;
case "MOVR": // command is MOVR(x, y)
GetTwoFloats(token,ref x, ref y);
cx += CPoint(x);
cy += CPoint(y);
break;
case "HLINE": // command is HLINE(x)
x = GetOneFloat(token);
grp.AppendChild(HorizontalLine(x));
break;
case "VLINE": // command is VLINE(y)
y = GetOneFloat(token);
grp.AppendChild(VerticalLine(y));
break;
case "DLINE": // command is DLINE(x, y)
GetTwoFloats(token, ref x, ref y);
grp.AppendChild(DiagLine(x, y));
break;
case "BOX": // command is BOX(x, y)
GetTwoFloats(token,ref x, ref y);
grp.AppendChild(Box(x,y));
break;
case "BOX3SIDES": // command is BOX3SIDES(X,Y)
GetTwoFloats(token, ref x, ref y);
XmlElement [] bxsd = new XmlElement[3];
bxsd = RTFBox3(x, y);
for (int ib = 0;ib < 3; ib++) grp.AppendChild(bxsd[ib]);
break;
case "DBOX": // * DBOX(X,Y,A) DoubleBox((double)X,(double)Y,(double)A);
MessageBox.Show("Not supported - ANO only");
break;
case "CIRCLE": // command is CIRCLE(X,Y)
GetTwoFloats(token, ref x, ref y);
grp.AppendChild(Ellipse(x,y));
break;
case "TEXT": // command is TEXT(x, y, str)
GetTwoFloats(token,ref x, ref y);
int indxrp = token.IndexOf(",");
indxrp = token.IndexOf(",",indxrp+1);
// this found the last argument, i.e. text - now find the "
indxrp = token.IndexOf("\"",indxrp+1);
string str = token.Substring(indxrp+1,token.LastIndexOf("\"")-indxrp-1);
// only trim if has characters?
// if (str!=null)str = str.Trim();
if (str!=null && str!="") grp.AppendChild(Text(x, y, str));
break;
case "BITMAP":
int ibm = token.IndexOf("BITMAP");
int ibmq = token.IndexOf("\"",ibm);
string thestr = token.Substring(ibm,ibmq-ibm);
string [] bmap = thestr.Split(" ".ToCharArray(),4);
x=(float)Convert.ToDouble(bmap[1]);
y=(float)Convert.ToDouble(bmap[2]);
thestr=bmap[3];
if (thestr.IndexOf("~FORMAT\\")>-1) thestr=thestr.Replace("~FORMAT","E:\\VE-PROMS\\FORMAT");
grp.AppendChild(BitMap(x,y,thestr));
break;
case "ABSOLUTE": // no-op ?
break;
default: // function calls
// see if in the STATICVOID list. The name is the function name
// without () or parameters...
XmlNode parent = functions.ParentNode;
XmlNode foundsv = parent.SelectSingleNode("STATICVOID[NAME = \""+cmd+"\"]");
if (foundsv==null)
Console.WriteLine("Name " + genName + " failed. The token is not in list, token = " +token);
else
{
XmlNode param = foundsv.SelectSingleNode("PARAMETERS");
XmlNode deffn = foundsv.SelectSingleNode("DEFINITION");
// get the argument value to pass in.
int ilp = token.IndexOf("(");
int irp = token.IndexOf(")");
string aval=null;
if (ilp>0&&irp>0) aval = token.Substring(ilp+1,irp-ilp-1);
ProcessFunctions(grp, param.InnerText,functions, aval, deffn.InnerText);
}
break;
}
}
catch (Exception e)
{
Console.WriteLine("Name = " + genName + ". Error in token: " + token, e.Message);
retval = null;
}
return;
}
private void ProcessFunctions(XmlElement grp, string param, XmlNode functions, string val, string fntext)
{
// Each function contains a series of commands that must be processed for the
// function. Results are added to the group element for this group (macro).
string repstr=null;
// if there is a parameter, get the substitution string...
if (param.IndexOf("none")==-1)
{
int chrindx = param.IndexOf("char *");
int end = -1;
if (chrindx>-1)
{
end = param.IndexOf("\"",chrindx);
repstr = param.Substring(chrindx+6,end-chrindx-6);
}
else
{
chrindx = param.IndexOf("int ");
if (chrindx>-1)
{
end = param.IndexOf("\"",chrindx);
repstr = param.Substring(chrindx+4,end-chrindx-4);
}
}
}
// find the function commands and include them here.
string funstr = fntext;
if (repstr!=null)funstr = funstr.Replace(repstr,val);
// for each element, process commands.
int lindx = 0;
int indx = funstr.IndexOf(";");
while (indx>-1)
{
ProcessToken(grp, funstr, lindx, indx, functions);
lindx = indx+1;
indx = funstr.IndexOf(";",lindx);
}
}
}
}