using System; using System.IO; using System.Xml; using System.Text; using System.Drawing; using System.Windows.Forms; namespace fmtxml { /// /// 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. /// 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, N = 0; 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; private string MyResultPath; /* * The following svg group must be added for WCN2 for its box on the cover page: * */ public GenXmlToSvg(string nm, string resPath) { MyResultPath = resPath; 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 if (Convertn == N) return (float)x; else // convert from x (in dots) to twips & then points return (float)(((4.8 * x + 0.5)/1440f)*72); } private void WriteXml() { string path = MyResultPath + @"\genmacall\" + 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 = MyResultPath + @"\genmacall\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 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) bool hasC0 = false; foreach (XmlNode nd in xmlNds) { XmlNode name = nd.SelectSingleNode("NAME"); XmlElement elm = (XmlElement) name; XmlElement grp = xmlOutDoc.CreateElement("g"); string cname = GetName(name.InnerText); if (cname == "CNUM") hasC0 = true; 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); } } // if the C0 (circle string) macro didn't exist, add a default. This is done so special code // does not have to be written to do the circle string in edit/print. /* Add the C0 macro if not there! */ if (!hasC0) { int savconvertn = Convertn; Convertn = 0; // don't convert size XmlElement grp = xmlOutDoc.CreateElement("g"); grp.SetAttribute("id", "C0"); topOutElement.AppendChild(grp); // these numbers were gotten from hlp backup circle. They may need adjusted // as genmacs are used! cx = -76; cy = -306; grp.AppendChild(Ellipse(430,450)); Convertn = savconvertn; } 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("href", 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); } } } }