Exemplo n.º 1
0
        internal static CGwGraph New(string aCode, CPoint aScreenSize, Action <string> aDebugPrint)
        {
            aCode = aCode.Replace(Environment.NewLine, " ");
            var aNodes  = new List <CGwNode>();
            var aEdges  = new List <CGwEdge>();
            var aParser = new CParser(aCode);

            aParser.SkipWhitespace();
            aParser.Expect("digraph");
            aParser.SkipWhitespace();
            var aDiagramName = aParser.ReadIdentifier();

            aParser.SkipWhitespace();
            aParser.Expect("{");
            aParser.SkipWhitespace();
            aParser.Expect("graph");
            aParser.SkipWhitespace();
            aParser.Expect("[");

            var aGraphAttributes = aParser.ReadAttributes();
            var aCoords          = aGraphAttributes["bb"].Trim();
            var aToks            = aCoords.Split(',').ToArray();
            var aDiagX           = aParser.ParseDouble(aToks[0]);
            var aDiagY           = aParser.ParseDouble(aToks[1]);
            var aDiagDx1         = aParser.ParseDouble(aToks[2]);
            var aDiagDy1         = aParser.ParseDouble(aToks[3]);

            ///////////////////////////////////////////////
            /// Klein, kein problem beim skalierungswechsel (sollte der zuletzt eingecheckte stand sein)
            var aDiagSize1  = new CPoint(aDiagDx1, aDiagDy1);
            var aDiagSize   = CPoint.GetSizeOfPreservedRatioScale(new CPoint(aDiagDx1, aDiagDy1), aScreenSize);
            var aScale      = 1.0d;
            var aScale1     = aDiagSize1 / aDiagSize;
            var aTranslate  = (aScreenSize - aDiagSize * aScale1) / new CPoint(2.0d);
            var aTranslateX = aTranslate.x;
            var aTranslateY = aTranslate.y;
            var aImportDx   = new Func <double, double>(c => c * aScale);
            var aImportDy   = new Func <double, double>(c => c * aScale);
            var aImportX    = new Func <double, double>(c => c * aScale + aTranslateX);
            var aImportY    = new Func <double, double>(c => c * aScale + aTranslateY);
            var aDiagDx     = aScreenSize.x;
            var aDiagDy     = aScreenSize.y;

            ///////////////////////////////////////////////
            // gross, problem beim skalierungswechsel,
            //var aDiagSize = CPoint.GetSizeOfPreservedRatioScale(new CPoint(aDiagDx1, aDiagDy1), aScreenSize);
            //var aScale = aDiagDx1 / aDiagSize.x;
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDx1=" + aDiagDx1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDy1=" + aDiagDy1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> Scale=" + aScale);
            //var aTranslate = (aScreenSize - aDiagSize) / new CPoint(2.0d);
            //var aTranslateX = aTranslate.x;
            //var aTranslateY = aTranslate.y;
            //var aImportDx = new Func<double, double>(c => c * aScale);
            //var aImportDy = new Func<double, double>(c => c * aScale);
            //var aImportX = new Func<double, double>(c => c * aScale + aTranslateX);
            //var aImportY = new Func<double, double>(c => c * aScale + aTranslateY);
            //var aDiagDx = aScreenSize.x;
            //var aDiagDy = aScreenSize.y;

            ///////////////////////////////////////////////
            // Noch probieren:
            //var aDiagSize = CPoint.GetSizeOfPreservedRatioScale(new CPoint(aDiagDx1, aDiagDy1), aScreenSize);
            //var aScale = aDiagDx1 / aDiagSize;
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDx1=" + aDiagDx1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDy1=" + aDiagDy1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> Scale=" + aScale);
            //var aTranslate = (aScreenSize - aDiagSize) / new CPoint(2.0d);
            //var aTranslateX = aTranslate.x;
            //var aTranslateY = aTranslate.y;
            //var aImportDx = new Func<double, double>(c => c * aScale.x);
            //var aImportDy = new Func<double, double>(c => c * aScale.y);
            //var aImportX = new Func<double, double>(c => c * aScale.x + aTranslateX);
            //var aImportY = new Func<double, double>(c => c * aScale.y + aTranslateY);
            //var aDiagDx = aScreenSize.x;
            //var aDiagDy = aScreenSize.y;


            ///////////////////////////////////////////////
            /// Gross, gut aber probleme beim skalierungswechswel:

            //var aDiagSize1 = new CPoint(aDiagDx1, aDiagDy1);
            //var aDiagSize = CPoint.GetSizeOfPreservedRatioScale(aScreenSize, new CPoint(aDiagDx1, aDiagDy1));
            //var aScale = aDiagSize / aDiagSize1;
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDx1=" + aDiagDx1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> DiagDy1=" + aDiagDy1);
            //aDebugPrint(">>>>>>>>>>>>>>>>>>>>> Scale=" + aScale);
            //var aTranslate = (aScreenSize - aDiagSize) / new CPoint(2.0d);
            //var aTranslateX = aTranslate.x;
            //var aTranslateY = aTranslate.y;
            //var aImportDx = new Func<double, double>(c => c * aScale.x);
            //var aImportDy = new Func<double, double>(c => c * aScale.y);
            //var aImportX = new Func<double, double>(c => c * aScale.x + aTranslateX);
            //var aImportY = new Func<double, double>(c => c * aScale.y + aTranslateY);
            //var aDiagDx = aScreenSize.x;
            //var aDiagDy = aScreenSize.y;
            ///////////////////////////////////////////////


            aParser.SkipWhitespace();
            aParser.Expect("]");
            aParser.SkipWhitespace();
            aParser.Expect(";");
            aParser.SkipWhitespace();
            while (aParser.Char != '}')
            {
                aParser.SkipWhitespace();
                var aNodeName1 = aParser.ReadIdentifier();
                aParser.SkipWhitespace();
                var aIsEdge = aParser.Is("->");
                if (aIsEdge)
                {
                    aParser.Expect("->");
                    aParser.SkipWhitespace();
                    var aTargetNodeName = aParser.ReadIdentifier();
                    aParser.SkipWhitespace();
                    aParser.Expect("[");
                    var aAttributes = aParser.ReadAttributes();
                    var aPos        = aAttributes["pos"]
                                      .Replace("\\ ", ""); // TODO ?!
                    var aPosParser = new CParser(aPos);
                    aPosParser.Expect("e,");
                    var aSplines = new List <CPoint>();
                    while (!aPosParser.IsEof)
                    {
                        var aX = aImportX(aPosParser.ParseDouble(aPosParser.ReadValue()));
                        aPosParser.Expect(",");
                        var aY     = aDiagDy - aImportY(aPosParser.ParseDouble(aPosParser.ReadValue()));
                        var aPoint = new CPoint(aX, aY);
                        aSplines.Add(aPoint);
                        aPosParser.SkipWhitespace();
                    }
                    var aColor = GetColor(aAttributes, "color");
                    aParser.SkipWhitespace();
                    aParser.Expect("]");
                    aParser.SkipWhitespace();
                    aParser.Expect(";");
                    aParser.SkipWhitespace();
                    var aEdge = new CGwEdge(aNodeName1, aTargetNodeName, aSplines, aColor);
                    aEdges.Add(aEdge);
                }
                else
                {
                    var aNodeName = aNodeName1;
                    aParser.SkipWhitespace();
                    aParser.Expect("[");
                    aParser.SkipWhitespace();
                    var aNodeAttributes = aParser.ReadAttributes();

                    aParser.SkipWhitespace();
                    aParser.Expect("]");
                    aParser.SkipWhitespace();
                    aParser.Expect(";");
                    if (aNodeAttributes.ContainsKey("pos"))
                    {
                        var aPos       = aNodeAttributes["pos"];
                        var aXy        = aPos.Split(',');
                        var aXText     = aXy[0];
                        var aYText     = aXy[1];
                        var aX         = aImportX(aParser.ParseDouble(aXText));
                        var aY         = aDiagDy - aImportY(aParser.ParseDouble(aYText));
                        var aDx        = aImportDx(InchesToPixels(aParser.ParseDouble(aNodeAttributes["width"])));
                        var aDy        = aImportDy(InchesToPixels(aParser.ParseDouble(aNodeAttributes["height"])));
                        var aShape     = aNodeAttributes["shape"];
                        var aColor     = GetColor(aNodeAttributes, "color");
                        var aFontColor = GetColor(aNodeAttributes, "fontcolor");
                        var aGwNode    = new CGwNode(aNodeName, aX, aY, aDx, aDy, aShape);
                        aGwNode.Color     = aColor;
                        aGwNode.FontColor = aFontColor;
                        aNodes.Add(aGwNode);
                    }
                }
                aParser.SkipWhitespace();
            }
            aParser.SkipWhitespace();
            aParser.Expect("}");
            aParser.SkipWhitespace();
            aParser.ExpectEndOfFile();

            var aGwGraph = new CGwGraph(aNodes.ToArray(),
                                        aEdges.ToArray(),
                                        new CPoint(aDiagDx, aDiagDy)
                                        );

            return(aGwGraph);
        }