Ejemplo n.º 1
0
        public Rect CalcSize(XdObjectJson xdObject, Rect rect)
        {
            var svg    = SvgUtil.CreateSvg(xdObject, null);
            var bounds = SvgUtil.CalcBounds(svg);

            return(bounds);
        }
Ejemplo n.º 2
0
        public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, XdAssetHolder assetHolder, IObbGetter obbGetter)
        {
            var components = new List <IComponent>();
            var assets     = new List <IAsset>();

            var color = xdObject.GetFillUnityColor();
            var svg   = SvgUtil.CreateSvg(xdObject);

            xdObject.Group.Children = new XdObjectJson[] { };

            var size      = obbGetter.Get(xdObject).Size;
            var spriteUid = $"{xdObject.GetSimpleName()}_{xdObject.Id.Substring(0, 8)}.png";
            var svgHash   = FastHash.CalculateHash(svg);

            var cachedSvg = assetHolder.GetCachedSvg(svgHash);

            if (cachedSvg != null)
            {
                spriteUid = cachedSvg.SpriteUid;
            }
            else
            {
                assets.Add(new SpriteAsset(spriteUid, svgHash, size, null, null));
                var xdImportSettings = XdImporter.Settings;
                assetHolder.Save(spriteUid, () => SvgToPng.Convert(svg, size, xdImportSettings));
                assetHolder.SaveCacheSvg(spriteUid, svgHash);
            }
            components.Add(new ImageComponent(
                               spriteUid,
                               new Color(1f, 1f, 1f, color.a),
                               Vector2Int.one
                               ));

            return(components.ToArray(), assets.ToArray());
        }
Ejemplo n.º 3
0
        static void Main(string[] args)
        {
            NestPath bin       = new NestPath();
            double   binWidth  = 75;
            double   binHeight = 41;

            bin.add(0, 0);
            bin.add(binWidth, 0);
            bin.add(binWidth, binHeight);
            bin.add(0, binHeight);
            Console.WriteLine("Bin Size : Width = " + binWidth + " Height=" + binHeight);
            //将多边形转换为坐标形式
            var nestPaths = SvgUtil.transferSvgIntoPolygons("test3.xml");

            Console.WriteLine("Reading File = test1.xml");
            Console.WriteLine("No of parts = " + nestPaths.Count);
            Config config = new Config();

            Console.WriteLine("Configuring Nest");
            Nest nest = new Nest(bin, nestPaths, config, 2);

            Console.WriteLine("Performing Nest");
            List <List <Placement> > appliedPlacement = nest.startNest();

            Console.WriteLine("Nesting Completed");
            var svgPolygons = SvgUtil.svgGenerator(nestPaths, appliedPlacement, binWidth, binHeight);

            Console.WriteLine("Converted to SVG format");
            SvgUtil.saveSvgFile(svgPolygons, "output.svg");
            Console.WriteLine("Saved svg file..Opening File");
            Process.Start("output.svg");
            Console.ReadLine();
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Get structure image with hilighting from a result link
        /// </summary>
        /// <param name="mc"></param>
        /// <param name="resultLink"></param>
        /// <param name="width"></param>
        /// <returns></returns>

        public override Bitmap GetImage(
            MetaColumn mc,
            string resultLink,
            int width)
        {
            string hls, rs;
            int    hitListId, rowId;

            Lex.Split(resultLink, ",", out hls, out rs);
            int.TryParse(hls, out hitListId);
            int.TryParse(rs, out rowId);

            DateTime t0 = DateTime.Now;

            if (SwDao != null && SwDao.Swp != null)
            {
                bool color = SwDao.Swp.Highlight;
                bool align = SwDao.Swp.Align;

                string svgXml = SwDao.GetDepiction(hitListId, rowId, color, align);
                Bitmap bm     = SvgUtil.GetBitmapFromSvgXml(svgXml, width);

                if (bm != null && BitmapCache != null)
                {
                    BitmapCache[resultLink] = bm;                     // cache the bitmap
                }
                return(bm);
            }

            else
            {
                throw new Exception("Failed to get image for " + mc.MetaTable.Name + "." + mc.Name);
            }
        }
Ejemplo n.º 5
0
        public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, XdAssetHolder assetHolder, IObbGetter obbGetter)
        {
            var obb      = obbGetter.Get(xdObject);
            var clipPath = xdObject.Meta.Ux.ClipPathResources.Children[0];

            if (SvgUtil.IsAlphaOnly(clipPath))
            {
                return(new IComponent[] { }, new IAsset[] { });
            }

            var(imageComponent, assets) = ShapeObjectParser.RenderImage(clipPath, obb, assetHolder);
            return(new IComponent[] { new MaskComponent(imageComponent.Sprite) }, assets);
        }
Ejemplo n.º 6
0
        public static Rect CalcSize(XdObjectJson xdObject)
        {
            var position      = Vector2.zero;
            var size          = Vector2.zero;
            var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill";

            var xdObjectShape = xdObject.Shape;
            var shapeType     = xdObjectShape.Type;

            if (SvgUtil.Types.Contains(shapeType))
            {
                var svg    = SvgUtil.CreateSvg(xdObject, null, true);
                var bounds = SvgUtil.CalcBounds(svg);
                if (bounds.width > 0.0001f && bounds.height > 0.0001f)
                {
                    size     = new Vector2(bounds.width, bounds.height);
                    position = new Vector2(bounds.x, bounds.y);
                }
            }

            if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f)
            {
                var imageWidth  = xdObject.Style?.Fill?.Pattern?.Width ?? 1f;
                var imageHeight = xdObject.Style?.Fill?.Pattern?.Height ?? 1f;
                var imageSize   = new Vector2(imageWidth, imageHeight);
                var imageAspect = imageSize.x / imageSize.y;
                var offsetX     = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f;
                var offsetY     = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f;
                var scale       = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f; // Widthに対するスケール

                var originalSize     = size;
                var originalPosition = position;

                size = new Vector2(
                    originalSize.x * scale,
                    originalSize.x * scale / imageAspect
                    );
                position = new Vector2(
                    originalPosition.x + (originalSize.x / 2f - size.x / 2f) + originalSize.x * offsetX,
                    originalPosition.y + (originalSize.y / 2f - size.y / 2f) + originalSize.x / imageAspect * offsetY
                    );
            }

            return(new Rect(position, size));
        }
Ejemplo n.º 7
0
        public static Bitmap HelmToBitmap(
            MoleculeMx mol,
            int pixWidth)
        {
            Bitmap bm = null;

            string svg = mol?.SvgString;
            string msg = String.Format("mol.Id: {0}, mol.Helm: {1}", mol?.Id, mol?.HelmString);

            try
            {
                if (mol.PrimaryFormat == MoleculeFormat.Helm && Lex.IsDefined(svg))
                {                 // if SVG available use it
                    bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth);

                    if (Debug)
                    {
                        DebugLog.Message(msg + " used existing SVG");
                    }
                    return(bm);
                }

                else
                {
                    string helm = mol.HelmString;
                    bm = HelmControl.GetBitmap(helm, pixWidth);
                    if (Debug)
                    {
                        DebugLog.Message(msg + " generated SVG");
                    }
                    return(bm);
                }
            }

            catch (Exception ex)
            {
                msg += "\r\n" + DebugLog.FormatExceptionMessage(ex);
                DebugLog.Message(msg);                 // log it
                return(null);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Load the browser with html to display the supplied SVG string
        /// </summary>
        /// <param name="svgString"></param>

        public void LoadSvgString(string svgString)
        {
            string html = SvgUtil.CreateHtlmWithSvgCenteredOnPage(svgString);

            LoadHtmlString(html);
        }
Ejemplo n.º 9
0
        public static (ImageComponent, IAsset[]) RenderImage(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder)
        {
            ImageComponent imageComponent = null;
            SpriteAsset    asset          = null;

            var color     = xdObject.GetFillUnityColor();
            var ux        = xdObject.Style?.Fill?.Pattern?.Meta?.Ux;
            var flipX     = ux?.FlipX ?? false;
            var flipY     = ux?.FlipY ?? false;
            var direction = new Vector2Int(flipX ? -1 : 1, flipY ? -1 : 1);
            var shapeType = xdObject.Shape?.Type;

            if (!string.IsNullOrWhiteSpace(ux?.Uid))
            {
                var spriteUid = $"{xdObject.GetSimpleName()}_{ux?.Uid.Substring(0, 8)}.png";
                asset          = new SpriteAsset(spriteUid, xdObject.Style.Fill.Pattern.Meta.Ux.HrefLastModifiedDate, obb.Size, null, null);
                imageComponent = new ImageComponent(
                    spriteUid,
                    color,
                    direction
                    );
                assetHolder.Save(spriteUid, xdObject.Style.Fill.Pattern.Meta);
            }
            else if (SvgUtil.Types.Contains(shapeType))
            {
                var spriteUid = $"{xdObject.GetSimpleName()}_{xdObject.Id.Substring(0, 8)}.png";
                var svg       = SvgUtil.CreateSvg(xdObject);
                var svgHash   = FastHash.CalculateHash(svg);

                var cachedSvg = assetHolder.GetCachedSvg(svgHash);
                if (cachedSvg != null)
                {
                    spriteUid = cachedSvg.SpriteUid;
                }
                else
                {
                    asset = new SpriteAsset(spriteUid, svgHash, obb.Size, null, null);
                    var xdImportSettings = XdImporter.Settings;
                    assetHolder.Save(spriteUid, () => SvgToPng.Convert(svg, obb.Size, xdImportSettings));
                    assetHolder.SaveCacheSvg(spriteUid, svgHash);
                }

                imageComponent = new ImageComponent(
                    spriteUid,
                    new Color(1f, 1f, 1f, color.a),
                    direction
                    );
            }
            else
            {
                Debug.LogError($"Unknown shape type {shapeType} in {xdObject.Name}({xdObject.Id}, {xdObject.Guid})");
            }

            var assets = new List <IAsset>();

            if (!xdObject.HasParameter("placeholder") && asset != null)
            {
                assets.Add(asset);
            }
            return(imageComponent, assets.ToArray());
        }
Ejemplo n.º 10
0
        public Rect CalcSize(XdObjectJson xdObject)
        {
            var position      = Vector2.zero;
            var size          = new Vector2(xdObject.Shape.Width, xdObject.Shape.Height);
            var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill";
            var spriteUid     = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Uid;

            var shapeType = xdObject.Shape?.Type;

            if (!string.IsNullOrWhiteSpace(spriteUid))
            {
                // nothing
            }
            else if (SvgUtil.Types.Contains(shapeType))
            {
                var svg = SvgUtil.CreateSvg(xdObject);
                using (var reader = new StringReader(svg))
                {
                    var sceneInfo   = SVGParser.ImportSVG(reader, ViewportOptions.DontPreserve);
                    var tessOptions = SvgToPng.TessellationOptions;
                    var geometry    = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions, sceneInfo.NodeOpacity);
                    var vertices    = geometry.SelectMany(geom => geom.Vertices.Select(x => (geom.WorldTransform * x))).ToArray();
                    var bounds      = VectorUtils.Bounds(vertices);
                    if (bounds.width > 0.0001f && bounds.height > 0.0001f)
                    {
                        size     = new Vector2(bounds.width, bounds.height);
                        position = new Vector2(bounds.x, bounds.y);
                    }
                }
            }

            if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f)
            {
                var imageWidth     = xdObject.Style?.Fill?.Pattern?.Width ?? 0f;
                var imageHeight    = xdObject.Style?.Fill?.Pattern?.Height ?? 0f;
                var imageSize      = new Vector2(imageWidth, imageHeight);
                var imageAspect    = imageSize.x / imageSize.y;
                var instanceAspect = size.x / size.y;
                var offsetX        = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f;
                var offsetY        = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f;
                var scale          = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f;

                if (imageAspect > instanceAspect)
                {
                    var prev = size.x;
                    size.x      = size.y * (imageSize.x / imageSize.y);
                    position.x -= (size.x - prev) / 2f;

                    position.x += offsetX * xdObject.Shape.Width * imageAspect / instanceAspect;
                    position.y += offsetY * xdObject.Shape.Height;
                }
                else
                {
                    var prev = size.y;
                    size.y      = size.x * (imageSize.y / imageSize.x);
                    position.y -= (size.y - prev) / 2f;

                    position.x += offsetX * xdObject.Shape.Width;
                    position.y += offsetY * xdObject.Shape.Height * imageAspect / instanceAspect;
                }

                {
                    var prev = size;
                    size     *= scale;
                    position -= (size - prev) / 2f;
                }
            }

            return(new Rect(position, size));
        }
Ejemplo n.º 11
0
        public static Rect CalcSize(XdObjectJson xdObject)
        {
            var position      = Vector2.zero;
            var size          = Vector2.zero;
            var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill";

            var shapeType = xdObject.Shape?.Type;

            if (shapeType == "rect")
            {
                size = new Vector2(xdObject.Shape.Width, xdObject.Shape.Height);
            }
            else if (SvgUtil.Types.Contains(shapeType))
            {
                var svg    = SvgUtil.CreateSvg(xdObject, null);
                var bounds = SvgUtil.CalcBounds(svg);
                if (bounds.width > 0.0001f && bounds.height > 0.0001f)
                {
                    size     = new Vector2(bounds.width, bounds.height);
                    position = new Vector2(bounds.x, bounds.y);
                }
            }

            if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f)
            {
                var imageWidth     = xdObject.Style?.Fill?.Pattern?.Width ?? 0f;
                var imageHeight    = xdObject.Style?.Fill?.Pattern?.Height ?? 0f;
                var imageSize      = new Vector2(imageWidth, imageHeight);
                var imageAspect    = imageSize.x / imageSize.y;
                var instanceAspect = size.x / size.y;
                var offsetX        = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f;
                var offsetY        = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f;
                var scale          = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f;

                if (imageAspect > instanceAspect)
                {
                    var prev = size.x;
                    size.x      = size.y * (imageSize.x / imageSize.y);
                    position.x -= (size.x - prev) / 2f;

                    position.x += offsetX * xdObject.Shape.Width * imageAspect / instanceAspect;
                    position.y += offsetY * xdObject.Shape.Height;
                }
                else
                {
                    var prev = size.y;
                    size.y      = size.x * (imageSize.y / imageSize.x);
                    position.y -= (size.y - prev) / 2f;

                    position.x += offsetX * xdObject.Shape.Width;
                    position.y += offsetY * xdObject.Shape.Height * imageAspect / instanceAspect;
                }

                {
                    var prev = size;
                    size     *= scale;
                    position -= (size - prev) / 2f;
                }
            }

            return(new Rect(position, size));
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Scale and translate structure and format into buffer
        /// </summary>
        /// <param name="mol">The structure</param>
        /// <param name="cellStyle">Style/conditional formatting to apply to cell</param>
        /// <param name="commandChar">Command character to use in buffer</param>
        /// <param name="x">Coordinate of left side of structure</param>
        /// <param name="width">Width of molecule box in milliinches</param>
        /// <param name="r">Row in buffer to put on. If less than 0 then return formatted data</param>
        /// <param name="heightInLines">number of lines used</param>

        public FormattedFieldInfo FormatStructure(
            MoleculeMx mol,
            CellStyleMx cellStyle,
            char commandChar,
            int x,
            int width,
            int r,
            ResultsField rfld = null,
            DataRowMx dataRow = null)
        {
            Rectangle destRect, boundingRect;
            int       height;       // formatted  height in milliinches
            bool      markBoundaries;
            int       fixedHeight;
            Bitmap    bm;
            Font      font;
            string    txt, molfile, molString = "", svg, cid = null;
            int       translateType, desiredBondLength = 100;
            int       pixWidth = 0, pixHeight = 0;

            bool debug = DataTableManager.DebugDetails;

            if (debug)
            {
                DebugLog.Message("=============================== FormattingStructure ===============================");
            }
            PerformanceTimer pt      = PT.Start("FormatStructure");
            Stopwatch        swTotal = Stopwatch.StartNew();
            Stopwatch        sw      = Stopwatch.StartNew();

            try
            {
                MoleculeFormat initialCsType  = mol.PrimaryFormat;
                string         initialCsValue = mol.PrimaryValue;

                QueryColumn qc = (rfld != null) ? rfld.QueryColumn : null;

                FormattedFieldInfo ffi = new FormattedFieldInfo();

                if (dataRow != null)                 // get any cid in row
                {
                    int ki = DataTableManager.DefaultKeyValueVoPos;
                    if (ki < dataRow.Length)
                    {
                        cid = dataRow[ki] as string;
                    }
                }

                //DebugLog.Message("FormatStructure " + cid);

                //if (!Rf.Grid) x = x; // debug

                ///////////////////////////////////
                // Highlight structure
                ///////////////////////////////////

                if (StructureHighlightPssc != null)
                {
                    ParsedStructureCriteria pssc = StructureHighlightPssc;

                    // Hilight substructure search match

                    if (pssc.SearchType == StructureSearchType.Substructure ||                     // regular SSS
                        pssc.SearchTypeUnion == StructureSearchType.Substructure)                  // handles related search for just SSS to get hilighting
                    {
                        if (HighlightStructureMatches)
                        {
                            try
                            {
                                mol = StrMatcher.HighlightMatchingSubstructure(mol);
                                if (DebugMx.False)                                 // debug
                                {
                                    //string highlightChildren = mol.MolLib.HighlightChildren;
                                    //Color highlightColor = mol.MolLib.HighlightColor;
                                    if (debug)
                                    {
                                        DebugLog.StopwatchMessage("tHilight", sw);
                                    }
                                }
                            }
                            catch (Exception ex) { ex = ex; }
                        }

                        if (AlignStructureToQuery)
                        {
                            try
                            {
                                mol = StrMatcher.AlignToMatchingSubstructure(mol);
                                if (debug)
                                {
                                    DebugLog.StopwatchMessage("tOrient", sw);
                                }
                            }
                            catch (Exception ex) { ex = ex; }
                        }
                    }

                    // Hilight SmallWorld structure match

                    else if (pssc.SearchType == StructureSearchType.SmallWorld)                     // Hilight SmallWorld structure search results
                    {
                        if (SmallWorldDepictions == null)
                        {
                            SmallWorldDepictions = new SmallWorldDepictions();
                        }

                        SmallWorldPredefinedParameters swp = pssc.SmallWorldParameters;

                        //DebugLog.Message("Depict " + cid + ", Hilight " + swp.Highlight + ", Align " + swp.Align); // + "\r\n" + new StackTrace(true));

                        if ((swp.Highlight || swp.Align) & Lex.IsDefined(cid))                         // call depiction for these
                        {
                            svg = SmallWorldDepictions.GetDepiction(cid, swp.Highlight, swp.Align);

                            if (Lex.IsDefined(svg))                             // have depiction?
                            {
                                {
                                    pixWidth            = MoleculeMx.MilliinchesToPixels(width);
                                    bm                  = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth);
                                    ffi.FormattedBitmap = mol.FormattedBitmap = bm;                                     // store in formatting info and chem structure
                                    return(ffi);
                                }
                            }

                            else if (svg == null)                             // start retrieval of this decpiction type & fall through to get default structure initially
                            {
                                SmallWorldDepictions.StartDepictionRetrieval(Qm, StructureHighlightQc, swp.Highlight, swp.Align);
                            }

                            else
                            {
                            }                                    // tried to get it but failed, fall through to get basic structure
                        }
                    }

                    else if (mol.AltFormDefined("Svg"))                     // svg form exist (e.g. SmallWorld or "related" structure search)?
                    {
                        svg = mol.SvgString;
                        if (Lex.IsDefined(svg))
                        {
                            pixWidth            = MoleculeMx.MilliinchesToPixels(width);
                            bm                  = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth);
                            ffi.FormattedBitmap = mol.FormattedBitmap = bm;                             // store in formatting info and chem structure
                            return(ffi);
                        }
                    }
                }

                ///////////////////////////////////
                // Handle each output device
                ///////////////////////////////////

                ffi.HeightInLines = 1;                 // min of 1 line

                if (Rf.SdFile)
                {
                    FormatSdfileStructure(mol);
                    return(null);
                }

                int pageHeight = 11000;
                if (Rf.PageMargins != null)
                {
                    pageHeight = Rf.PageMargins.Top + Rf.PageHeight + Rf.PageMargins.Bottom;
                }

                if (Rf.Excel || Rf.Word)
                {
                    translateType = 2;
                }
                else
                {
                    translateType = 0;
                }

                if (!Rf.FixedHeightStructures)
                {
                    fixedHeight = 0;                                            // not fixed height
                }
                else if (Rf.Excel || Rf.Word)
                {
                    fixedHeight = 1;                                           // always fixed height
                }
                else
                {
                    fixedHeight = 2;                  // fixed height unless need to expand
                }
                if (Rf.Word && Rf.FixedHeightStructures)
                {
                    markBoundaries = true;
                }
                else
                {
                    markBoundaries = false;
                }

                destRect = new Rectangle(0, 0, width, width * 4 / 5);                 // default dest rect

                ///////////////////////////////////////////////////////////////////////////
                // Tempory fake generation of HELM & associatedimage for biopolymer testing
                ///////////////////////////////////////////////////////////////////////////

                //if (MoleculeMx.HelmEnabled == DebugMx.False) // artificially generate helm molecules
                //	MoleculeMx.SetMoleculeToTestHelmString(mol.GetCorpId().ToString(), mol);

                ///////////////////////////////////////////////////////////////////////////
                // End of tempory fake generation of HELM & associatedimage for biopolymer testing
                ///////////////////////////////////////////////////////////////////////////

                bool fitStructure = true;

                if (mol.IsChemStructureFormat)
                {
                    if (Rf.Grid)                     // special scale for grid
                    {
                        double scale = (float)width / MoleculeMx.StandardBoxWidth;
                        desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale));
                        //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0));
                        desiredBondLength = (int)(desiredBondLength * 90.0 / 100.0);                         // scale down a bit for grid
                        if (debug)
                        {
                            DebugLog.StopwatchMessage("tAdjustBondLength1", sw);
                        }
                    }

                    else                     // set desired bond length based on page scaling
                    {
                        float scale = (float)width / MoleculeMx.StandardBoxWidth;
                        desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale));
                        //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0));
                        if (debug)
                        {
                            DebugLog.StopwatchMessage("tAdjustBondLength2", sw);
                        }
                    }

                    if (desiredBondLength < 1)
                    {
                        desiredBondLength = 1;
                    }
                    if (debug)
                    {
                        DebugLog.StopwatchMessage("tBeforeFit", sw);
                    }

                    if (fitStructure)
                    {
                        mol.CdkMol.FitStructureIntoRectangle                         // scale and translate structure into supplied rectangle.
                            (ref destRect, desiredBondLength, translateType, fixedHeight, markBoundaries, pageHeight, out boundingRect);
                    }

                    if (debug)
                    {
                        DebugLog.StopwatchMessage("tFitStructure", sw);
                    }

                    ffi.HeightInLines = (int)(destRect.Height / Rf.LineHeight + 1);                     // lines needed
                }

                else if (mol.IsBiopolymerFormat)
                {
                    if (mol.PrimaryFormat == MoleculeFormat.Helm && Rf.Excel)
                    {
                        svg = HelmControl.GetSvg(mol.HelmString);
                        float           inchWidth = width / 1000.0f;               // convert width milliinches to inches
                        Svg.SvgDocument svgDoc    = SvgUtil.AdjustSvgDocumentToFitContent(svg, inchWidth, Svg.SvgUnitType.Inch);
                        RectangleF      svgbb     = svgDoc.Bounds;
                        float           ar        = svgbb.Width / svgbb.Height; // aspect ratio of svg bounding box

                        height            = (int)(width / ar);                  // height in milliinches
                        ffi.HeightInLines = (int)(height / Rf.LineHeight) + 1;  // lines needed

                        destRect = new Rectangle(0, 0, width, height);
                    }
                }

                //////////////////////////
                /// Output to Grid
                //////////////////////////

                if (Rf.Grid)
                {
                    pixWidth  = MoleculeMx.MilliinchesToPixels(destRect.Width);
                    pixHeight = MoleculeMx.MilliinchesToPixels(destRect.Height);

                    if (cellStyle == null)
                    {
                        if (Qm == null || Qm.MoleculeGrid == null)
                        {
                            font = new Font("Tahoma", 8.25f);
                        }
                        else
                        {
                            font = new Font(Qm.MoleculeGrid.Font, FontStyle.Underline);
                        }
                        cellStyle = new CellStyleMx(font, Color.Blue, Color.Empty);
                    }

                    if (mol.IsChemStructureFormat)                     // molfile type molecule
                    {
                        if (debug)
                        {
                            DebugLog.StopwatchMessage("tBeforeGetDisplayPreferences", sw);
                        }
                        DisplayPreferences dp = mol.GetDisplayPreferences();
                        if (debug)
                        {
                            DebugLog.StopwatchMessage("tGetDisplayPreferences", sw);
                        }

                        //desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange(desiredBondLength); // be sure bond len within allowed range
                        //if (debug) DebugLog.StopwatchMessage("tAdjustBondLengthToValidRange", sw);
                        //dp.StandardBondLength = MoleculeMx.MilliinchesToDecipoints(desiredBondLength);
                        bm = mol.CdkMol.GetFixedHeightMoleculeBitmap(pixWidth, pixHeight, dp, cellStyle, mol.Caption);
                        if (debug)
                        {
                            DebugLog.StopwatchMessage("tGetBitmap", sw);
                        }
                    }

                    else if (mol.IsBiopolymerFormat)                     // Output HELM image for biopolymer
                    {
                        pixWidth = MoleculeMx.MilliinchesToPixels(width);
                        bm       = HelmConverter.HelmToBitmap(mol, pixWidth);
                    }

                    else
                    {
                        bm = new Bitmap(1, 1);
                    }

                    ffi.FormattedBitmap = mol.FormattedBitmap = bm;      // store in formatting & structure
                    ffi.FormattedText   = "Formatted";                   // indicate formatted (could save structure string but not needed and avoids possible conversion overhead)
                    return(ffi);
                }

                //////////////////////////
                /// Output to Html
                //////////////////////////

                else if (Rf.Html)
                {
                    if (r >= 0)
                    {
                        AssureTbFree(0, r + ffi.HeightInLines - 1);
                    }

                    if (mol.IsChemStructureFormat)
                    {
                        FormatChemStructureHtml(mol, destRect, width, r);
                    }

                    else if (mol.IsBiopolymerFormat)
                    {
                        FormatBiopolymerStructureHtml(mol, destRect, width, r);
                    }

                    if (debug)
                    {
                        DebugLog.StopwatchMessage("tFormatHtmlStructure", sw);
                    }

                    ffi.FormattedBitmap = mol.FormattedBitmap;
                    ffi.FormattedText   = mol.FormattedText;
                    return(ffi);
                }

                /////////////////////////////////////////////////////////////////
                /// Other format, store Smiles or Helm & any cellStyle in buffer
                /////////////////////////////////////////////////////////////////

                else
                {
                    if (mol.IsChemStructureFormat)
                    {
                        if (Rf.ExportStructureFormat == ExportStructureFormat.Smiles)
                        {
                            molString = mol.GetSmilesString();
                        }
                        else
                        {
                            molString = mol.GetChimeString();                          // use Chime if not smiles
                        }
                    }

                    else if (mol.IsBiopolymerFormat)
                    {
                        molString = mol.PrimaryValue;                         // usually Helm but could be sequence
                    }

                    txt = String.Format("{0} {1} {2} {3} {4} {5} {6}",
                                        x, width, destRect.Left, destRect.Top, destRect.Right, destRect.Bottom, molString);

                    if (cellStyle != null)                     // apply style to cell?
                    {
                        txt += " <CellStyle " + cellStyle.Serialize() + ">";
                    }

                    txt = commandChar + " " + txt + "\t";

                    if (r >= 0)
                    {
                        AssureTbFree(0, r + ffi.HeightInLines - 1);
                        Tb.Lines[r] += txt;                         // put in buffer
                    }

                    else
                    {
                        return(new FormattedFieldInfo(txt));                     // just return formatting
                    }
                }

                return(null);
            }

            catch (Exception ex)
            {
                DebugLog.Message(DebugLog.FormatExceptionMessage(ex));
                return(null);
            }

            finally
            {
                pt.Update();
                int formatCount = pt.Count;
                //ClientLog.Message(pt.ToString() + ", " + cs.GetMolHeader()[2]); // + ", " + new StackTrace(true));
                if (debug)
                {
                    DebugLog.StopwatchMessage("tTotalTime", swTotal);
                }
            }
        }
Ejemplo n.º 13
0
/// <summary>
/// Retrieve any existing SVG for the list of supplied molecules
/// The Id column should contain the CorpId
/// </summary>
/// <param name="molList"></param>

        public static int SelectMoleculeListSvg(
            List <MoleculeMx> molList)
        {
            MoleculeMx mol;
            int        corpId, molSvgsFetchedCount = 0;
            string     corpIdString, molString, svg;

            const string sql = @"
		SELECT 
      corp_nbr,
      molstructure svgString
    FROM 
			mbs_owner.corp_moltable_mx
    WHERE 
      corp_nbr in (<list>)
			and molstructure is not null
		"        ;

            if (!Security.UserInfo.Privileges.CanRetrieveStructures)                     // structures allowed?
            {
                return(0);
            }

            //if (DebugMx.True) return 0; // debug, don't use existing values

            List <string> lsnList = new List <string>();
            Dictionary <string, MoleculeMx> molDict = new Dictionary <string, MoleculeMx>();

            foreach (MoleculeMx mol0 in molList)                     // set up a dict keyed by cid with mol values
            {
                if (mol0.PrimaryFormat != MoleculeFormat.Helm || Lex.IsUndefined(mol0.PrimaryValue))
                {
                    continue;
                }

                if (int.TryParse(mol0.Id, out corpId))
                {
                    molDict[mol0.Id] = mol0;
                }
            }

            if (molDict.Count == 0)
            {
                return(0);
            }

            DbCommandMx cmd = new DbCommandMx();

            cmd.PrepareListReader(sql, DbType.String);
            cmd.ExecuteListReader(new List <string>(molDict.Keys));

            while (cmd.Read())
            {
                corpId = cmd.GetInt(0);

                if (!cmd.IsNull(1))                         // molstructure
                {
                    molString = cmd.GetClob(1);

                    if (!SvgUtil.IsSvgString(molString))
                    {
                        continue;                                // skip if not SVG
                    }
                    svg = molString;                             // should be compressed format SVG

                    corpIdString = CompoundId.Normalize(corpId.ToString());

                    if (Lex.IsDefined(svg) && molDict.ContainsKey(corpIdString))
                    {
                        mol           = molDict[corpIdString];
                        mol.SvgString = svg;
                        molSvgsFetchedCount++;
                    }
                }
            }

            cmd.CloseReader();

            return(molSvgsFetchedCount);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Sync the Mobius CorpMoltable replicate used to retrieve Smiles
        /// Syntax: UpdateCorpDbMoltableMx [ ByDateRange | ByCorpIdRange | LoadMissing | <singleCorpId>]
        /// </summary>
        /// <returns></returns>

        public static string UpdateCorpDbMoltableMx(
            string args)
        {
            DateTime moleculeDateTime = DateTime.MinValue;
            double   mw;
            string   msg = "", sql = "", maxCorpIdSql, mf = "", chime = "", smiles = "", checkPointDate = "", helm = "", sequence = "", svg = "";

            object[][] pva = null;
            int        pvaCount = 0, CorpId, lowCorpId = 0, highCorpId = 0, srcMaxCorpId = 0;

            int SelectChunkSize  = 20;            // small chunks
            int InsertBufferSize = 10;

            //int SelectChunkSize = 100000; // big chunks
            //int InsertBufferSize = 1000;

            // Select data from corp_moltable by CorpId range

            const string SelectByCorpIdRange = @" 
		SELECT 
        m.corp_nbr,
        chime(m.ctab), 
        m.molformula,
        m.molweight,
        null molsmiles,
        s.helm_txt,
        s.sequence_txt,
        m.molecule_date
    FROM 
        corp_owner.corp_moltable m,
        corp_owner.corp_substance s
    where 
        m.corp_nbr > 0
        and s.corp_nbr = m.corp_nbr
        and (s.status_code is null or s.status_code = 'A')    
    ORDER BY corp_nbr";

            // Select data from corp_moltable by date range comparing to corp_moltable_mx

            const string SelectByDateRange = @"
			select
					m.corp_nbr,
					chime(m.ctab), 
					m.molformula,
					m.molweight,
          null molsmiles,
	        s.helm_txt,
					s.sequence_txt,
					m.molecule_date,
					m2.molecule_date
			from
					corp_owner.corp_moltable m,
					corp_owner.corp_substance s,
					corp_moltable_mx m2
			where
					m.molecule_date > to_date('1-jan-1900 000000','DD-MON-YYYY HH24MISS')
					and s.corp_nbr = M.CORP_NBR
					and (s.status_code is null or s.status_code = 'A')    
					and m2.corp_nbr (+) = m.corp_nbr
					and m2.molecule_date (+) != m.molecule_date
			order by m.molecule_date"            ;

            // Select for missing smiles strings, ex: Update CorpDbMoltableMx LoadMissing mx.molecule_date > '1-jan-2014'

            const string SelectMissingSmilesFix = @"
			select /* check for CorpIds in corp_moltable not in corp_moltable_mx */
					corp_nbr,
					chime(ctab), 
					molformula,
					molweight,
					null molsmiles,
					helm_txt,
          sequence_txt,
          molecule_date
			from 
					(
					select 
						m.*, 
						s.helm_txt,
						s.sequence_txt,
						mx.molsmiles molsmiles_mx
					from
					 corp_owner.corp_moltable m,
					 corp_owner.corp_substance s,
					 corp_moltable_mx mx
					where
					 s.corp_nbr = M.CORP_NBR
					 and (s.status_code is null or s.status_code = 'A')
					 and mx.corp_nbr (+) = m.corp_nbr
					 and 1=1 /* condition to substitute */
					) m
			where molsmiles_mx is null /* extra condition */
			order by corp_nbr"            ;

// Insert missing helm info

            const string SelectMissingHelmFix = @"
			select /* check for CorpIds in corp_moltable not in corp_moltable_mx */
					corp_nbr,
					chime(ctab), 
					molformula,
					molweight,
					null molsmiles,
					helm_txt,
          sequence_txt,
          molecule_date
			from 
					(
					select 
						m.*, 
						s.helm_txt,
						s.sequence_txt,
						mx.molsmiles molsmiles_mx
					from
					 corp_owner.corp_moltable m,
					 corp_owner.corp_substance s,
					 corp_moltable_mx mx
					where
					 s.corp_nbr = M.CORP_NBR
					 and (s.status_code is null or s.status_code = 'A')
					 and mx.corp_nbr (+) = m.corp_nbr
					 and 1=1 /* condition to substitute */
					) m
			where length(helm_txt) > 0 /* extra condition */
			order by corp_nbr"            ;

            // Secondary "large" structure table (~5k mols)

            const string SelectLargeMols = @"
			select 
				corp_nbr, 
				to_clob(molstructure), 
				to_clob(molformula), 
				molweight,
				molsmiles,
				null helm_txt,
				null sequence_txt,
				molecule_date
			from
			(select
				corp_srl_nbr corp_nbr,
				'CompoundId=' || corp_srl_nbr molstructure, 
				null ctab,
				mlclr_frml_txt molformula,
				mlclr_wgt molweight,
				null molsmiles,
				null molecule_date
				from rdm_owner.rdm_sbstnc 
				where rdw_src_cd = 'LRG'"                ;

// Insert statement

            const string InsertSql = @"
			insert into mbs_owner.corp_moltable_mx (
				corp_nbr,
				molstructure,
				molformula,
				molweight,
				molsmiles,
				molecule_date)
			values (:0, :1, :2, :3, :4, :5)"            ;

// Build select sql

            bool   byDateRange = false, byCorpIdRange = false, missingFix = true, deleteExisting = true;
            string missingFixCriteria = "";

            if (Lex.IsUndefined(args) || Lex.Eq(args, "ByDateRange"))
            {
                byDateRange = true;
            }

            else if (Lex.Eq(args, "ByCorpIdRange"))
            {
                byCorpIdRange = true;

                Progress.Show("Getting range of CorpIds to insert...");
                maxCorpIdSql = "select max(corp_nbr) from corp_owner.corp_moltable";                 // get highest CorpId in source db
                srcMaxCorpId = SelectSingleValueDao.SelectInt(maxCorpIdSql);
                if (srcMaxCorpId < 0)
                {
                    srcMaxCorpId = 0;
                }

                maxCorpIdSql = "select max(corp_nbr) from mbs_owner.corp_moltable_mx";                 // get highest CorpId in dest db
                highCorpId   = SelectSingleValueDao.SelectInt(maxCorpIdSql);
                if (highCorpId < 0)
                {
                    highCorpId = 0;
                }
            }

            else if (Lex.StartsWith(args, "LoadMissing"))
            {
                missingFix = true;
                if (args.Contains(" "))
                {
                    missingFixCriteria = args.Substring(10).Trim();
                }
            }

            else if (int.TryParse(args, out srcMaxCorpId))             // single CorpId
            {
                byCorpIdRange = true;
                highCorpId    = srcMaxCorpId - 1;              // say 1 less is the max we have
            }

            else
            {
                return("Syntax: UpdateCorpDbMoltableMx [ ByDateRange | ByCorpIdRange | LoadMissing | <singleCorpId>]");
            }

            Log("UpdateCorpDbMoltableMx started: " + args);

            int           readCount = 0, insCount = 0, insertCount = 0, updateCount = 0, undefinedStructures = 0, smilesSuccess = 0, smilesFails = 0, helmStructures = 0;
            List <string> CorpIdList = new List <string>();

            for (int chunk = 1; ; chunk++)       // loop over chunks
            {
                if (byDateRange)                 // single chunk
                {
                    if (chunk > 1)
                    {
                        break;                                // break 2nd time through
                    }
                    checkPointDate = UserObjectDao.GetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", "01-sep-2013 000000");

                    //UserObjectDao.SetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", checkPointDate);

                    sql = Lex.Replace(SelectByDateRange, "1-jan-1900 000000", checkPointDate);

                    msg = "Reading where date >= " + checkPointDate;
                }

                else if (byCorpIdRange)                 // by CorpId range
                {
                    if (highCorpId >= srcMaxCorpId)
                    {
                        break;                                      // done
                    }
                    lowCorpId  = highCorpId + 1;                    // start of next chunk
                    highCorpId = lowCorpId + SelectChunkSize;
                    if (highCorpId >= srcMaxCorpId)
                    {
                        highCorpId = srcMaxCorpId;
                    }
                    sql = Lex.Replace(SelectByCorpIdRange, "corp_nbr > 0", "corp_nbr between " + lowCorpId + " and " + highCorpId);

                    msg = "Reading: " + lowCorpId + " to " + highCorpId + ", Reads: " + readCount + ", Inserts: " + insertCount;
                }

                else if (missingFix)
                {
                    if (chunk > 1)
                    {
                        break;                                // break 2nd time through
                    }
                    sql = SelectMissingHelmFix;
                    if (Lex.IsDefined(missingFixCriteria))                     // substitute any criteria
                    {
                        sql = Lex.Replace(sql, "1=1", missingFixCriteria);
                    }
                    msg = "Fixing missing data";
                }

                Progress.Show(msg);

                DbCommandMx readCmd = new DbCommandMx();
                readCmd.MxConn = DbConnectionMx.GetConnection("prd123");
                readCmd.PrepareUsingDefinedConnection(sql, null);
                DbDataReader rdr = readCmd.ExecuteReader();

                DbCommandMx insertCmd = new DbCommandMx();

                OracleDbType[] pta = new OracleDbType[6];
                pta[0] = OracleDbType.Int32;                // corp_nbr
                pta[1] = OracleDbType.Clob;                 // molstructure
                pta[2] = OracleDbType.Clob;                 // molformula
                pta[3] = OracleDbType.Double;               // molweight
                pta[4] = OracleDbType.Clob;                 // smiles
                pta[5] = OracleDbType.Date;                 // molecule_date

                insertCmd.Prepare(InsertSql, pta);
                insertCmd.BeginTransaction();                               // be sure we have a transaction going

                pva = DbCommandMx.NewObjectArrayArray(6, InsertBufferSize); // alloc insert row array
                object[] vo = new object[6];

                while (true)
                {
                    bool readOk = rdr.Read();

                    if (readOk)
                    {
                        rdr.GetValues(vo);

                        CorpId = readCmd.GetInt(0);                         // corp_nbr
                        vo[0]  = CorpId;
                        CorpIdList.Add(CorpId.ToString());

                        if (!readCmd.IsNull(1))                         // molstructure
                        {
                            chime = readCmd.GetClob(1);
                            chime = OracleMx.ClearStringIfExceedsMaxStringSize(chime);
                            vo[1] = chime;
                        }
                        else
                        {
                            chime = "";
                        }

                        if (!readCmd.IsNull(2))                         // molformula
                        {
                            mf    = readCmd.GetClob(2);
                            mf    = OracleMx.ClearStringIfExceedsMaxStringSize(mf);
                            vo[2] = mf;
                        }

                        if (!readCmd.IsNull(3))                         // molweight
                        {
                            mw    = readCmd.GetDouble(3);
                            vo[3] = mw;
                        }

                        if (Lex.IsDefined(chime))                         // molsmiles - calculate from chime string
                        {
                            MoleculeMx cs = new MoleculeMx(MoleculeFormat.Chime, chime);
                            if (cs.AtomCount > 1)                             // need more than one atom
                            {
                                MoleculeMx cs2 = cs.ConvertTo(MoleculeFormat.Smiles);
                                smiles = cs2.GetSmilesString();
                                if (Lex.IsDefined(smiles))
                                {
                                    smilesSuccess++;
                                }
                                else
                                {
                                    Log("Smiles conversion failure for CorpId: " + CorpId);
                                    smilesFails++;
                                }
                                smiles = OracleMx.ClearStringIfExceedsMaxStringSize(smiles);

                                vo[4] = smiles;
                            }
                            else
                            {
                                undefinedStructures++;
                            }
                        }
                        else
                        {
                            undefinedStructures++;
                        }

                        if (!readCmd.IsNull(5))
                        {
                            helm = readCmd.GetClob(5);
                            if (Lex.IsDefined(helm))
                            {
                                svg   = HelmControl.GetSvg(helm);
                                vo[1] = SvgUtil.CompressSvgString(svg);                                 // store compressed svg in molstructure column for now
                                helmStructures++;
                            }
                        }

                        if (!readCmd.IsNull(6))
                        {
                            sequence = readCmd.GetClob(6);
                            if (Lex.IsDefined(sequence))
                            {
                                // nothing yet
                            }
                        }

                        moleculeDateTime = DateTime.MinValue;
                        if (!readCmd.IsNull(7))                         // molecule_date
                        {
                            moleculeDateTime = readCmd.GetDateTime(7);
                            vo[5]            = moleculeDateTime;
                        }

                        for (int pi = 0; pi < 6; pi++)                         // invert for insert
                        {
                            pva[pi][pvaCount] = vo[pi];
                        }

                        if (Debug)
                        {
                            msg = String.Format("CorpId: {0}, mf: {1}, chime: {2}, smiles: {3}", CorpId.ToString(), mf.Length, chime.Length, smiles.Length);
                            Log(msg);
                        }

                        pvaCount++;
                    }

                    if (pvaCount >= InsertBufferSize || (!readOk && pvaCount > 0))                     // write if buffer full or at end
                    {
                        try
                        {
                            if (deleteExisting)
                            {
                                int delCount = DoDeletes(CorpIdList);
                                updateCount += delCount;                                 // count deletes as updates
                                insertCount -= delCount;                                 // subtract from inserts
                            }
                            CorpIdList.Clear();

                            insCount = insertCmd.ExecuteArrayNonReader(pva, ref pvaCount);
                            insertCmd.Commit();
                            insertCmd.BeginTransaction();
                            insertCount += insCount;
                        }

                        catch (Exception ex)
                        {
                            throw new Exception(ex.Message, ex);
                        }

                        if (byDateRange)
                        {
                            string checkPointDate2 = String.Format("{0:dd-MMM-yyyy HHmmss}", moleculeDateTime);                             // format date time that will work with oracle
                            UserObjectDao.SetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", checkPointDate2);
                            msg = "Processing where date >= " + checkPointDate + ", Reads: " + readCount + ", Inserts: " + insertCount + ", Updates: " + updateCount;
                        }

                        else if (byCorpIdRange)                         // CorpId range
                        {
                            msg = "Processing: " + lowCorpId + " to " + highCorpId + ", Reads: " + readCount + ", Inserts: " + insertCount;
                        }

                        else if (missingFix)
                        {
                            msg = "Fixing missing smiles, Updates: " + updateCount;
                        }

                        msg += String.Format(", Undefined structures: {0} , Smiles failures: {1}, Helms: {2}", undefinedStructures, smilesFails, helmStructures);

                        Progress.Show(msg);
                    }

                    if (!readOk)
                    {
                        break;
                    }

                    readCount++;
                }

                readCmd.Dispose();
                insertCmd.Dispose();
            }             // end for select chunk

            msg  = "UpdateCorpDbMoltableMx - Inserts: " + insertCount + ", Updates: " + updateCount;
            msg += String.Format(", Undefined structures: {0} , Smiles failures: {1}, Helms: {2}", undefinedStructures, smilesFails, helmStructures);
            Log(msg);

            return(msg);
        }
Ejemplo n.º 15
0
/// <summary>
/// RenderMolecule
/// </summary>

        public void RenderMolecule()
        {
            Rectangle destRect = this.Bounds, boundingRect;
            string    svg;

            Svg.SvgDocument svgDoc;
            Bitmap          bm;
            int             height; // formatted  height in milliinches
            bool            markBoundaries = false;
            int             fixedHeight = 0, translateType = 0, desiredBondLength = 100, pageHeight = 11000;
            int             miWidth;

            if (MolFormat == MoleculeFormat.Unknown || Lex.IsUndefined(MolString))
            {
                ImageCtl.SvgImage = null;
                ImageCtl.Image    = null;
                return;
            }

            svg = CdkMol.GetMoleculeSvg(this.Width, this.Height); // get svg

            if (DebugMx.False)                                    // Create bitmap from CdkMol
            {
                bm             = CdkMol.GetMoleculeBitmap(this.Width, this.Height);
                ImageCtl.Image = bm;
                return;
            }

            if (DebugMx.False)             // Create svg, then get bitmap
            {
                bm             = SvgUtil.GetBitmapFromSvgXml(svg, this.Width);
                ImageCtl.Image = bm;
                return;
            }

            if (DebugMx.False)             // Fit structure, then get bitmap
            {
                int    stdBoxWidthPx = Mobius.Data.MoleculeMx.MilliinchesToPixels(Mobius.Data.MoleculeMx.StandardBoxWidth);
                double scale         = (float)this.Width / stdBoxWidthPx;
                desiredBondLength = CdkMol.AdjustBondLengthToValidRange((int)(Mobius.Data.MoleculeMx.StandardBondLength * scale));                 // (not implemented)
                if (desiredBondLength < 1)
                {
                    desiredBondLength = 1;
                }

                CdkMol.FitStructureIntoRectangle                 // scale and translate structure into supplied rectangle.
                    (ref destRect, desiredBondLength, translateType, fixedHeight, markBoundaries, pageHeight, out boundingRect);

                bm             = CdkMol.GetMoleculeBitmap(this.Width, this.Height);
                ImageCtl.Image = bm;
                return;
            }

            if (DebugMx.True)                                                    // Create control SvgImage directly from SVG
            {
                MemoryStream ms     = StreamConverter.StringToMemoryStream(svg); // convert SVG to image for control
                SvgImage     svgImg = new SvgImage(ms);
                ImageCtl.SvgImage = svgImg;
                return;
            }

            if (DebugMx.True)
            {
                //miWidth = MoleculeMx.PixelsToMilliinches(this.Width);
                //float inchWidth = miWidth / 1000.0f; // convert width milliinches to inches
                //svgDoc = SvgUtil.AdjustSvgDocumentToFitContent(svg, inchWidth, Svg.SvgUnitType.Inch);

                string newSvg = SvgUtil.AdjustSvgToFitContent(svg, this.Width, Svg.SvgUnitType.Pixel, out svgDoc);
                ImageCtl.Image = svgDoc.Draw(ImageCtl.Width, ImageCtl.Height);

                //bm = SvgUtil.GetBitmapFromSvgXml(newSvg, this.Width);
                //ImageCtl.Image = bm;
                return;
            }
        }