예제 #1
0
        /// <summary>
        /// Returns the drawing color of the given atom. An atom is colored as
        /// highlighted if highlighted. The atom is color marked if in a
        /// substructure. If not, the color from the CDK2DAtomColor is used (if
        /// selected). Otherwise, the atom is colored black.
        /// </summary>
        protected internal virtual Color GetAtomColor(IAtom atom, RendererModel model)
        {
            var atomColor = model.GetAtomColor();

            if (model.GetAtomColorByType())
            {
                atomColor = model.GetAtomColorer().GetAtomColor(atom);
            }
            return(atomColor);
        }
예제 #2
0
 /// <summary>
 /// Create a new generator for a molecule.
 /// </summary>
 /// <param name="mol">molecule</param>
 /// <param name="font">the font</param>
 /// <param name="emSize">the font size</param>
 /// <param name="model">the rendering parameters</param>
 public StandardDonutGenerator(IAtomContainer mol, Typeface font, double emSize, RendererModel model, double stroke)
 {
     this.mol               = mol;
     this.font              = font;
     this.emSize            = emSize;
     this.forceDelocalised  = model.GetForceDelocalisedBondDisplay();
     this.delocalisedDonuts = model.GetDelocalisedDonutsBondDisplay();
     this.dbSpacing         = model.GetBondSeparation();
     this.scale             = model.GetScale();
     this.stroke            = stroke;
     this.fgColor           = model.GetAtomColorer().GetAtomColor(CDK.Builder.NewAtom("C"));
 }
예제 #3
0
        /// <inheritdoc/>
        public IRenderingElement Generate(IAtomContainer container, RendererModel parameters)
        {
            if (container.Atoms.Count == 0)
            {
                return(new ElementGroup());
            }

            var symbolRemap = new Dictionary <IAtom, string>();

            StandardSgroupGenerator.PrepareDisplayShortcuts(container, symbolRemap);

            var scale = parameters.GetScale();

            var visibility      = parameters.GetVisibility();
            var coloring        = parameters.GetAtomColorer();
            var annotationColor = parameters.GetAnnotationColor();
            var foreground      = coloring.GetAtomColor(container.Builder.NewAtom("C"));

            // the stroke width is based on the font. a better method is needed to get
            // the exact font stroke but for now we use the width of the pipe character.
            var fontStroke = new TextOutline("|", font, emSize).Resize(1 / scale, 1 / scale).GetBounds().Width;
            var stroke     = parameters.GetStrokeRatio() * fontStroke;

            var annotations = new ElementGroup();

            var donutGenerator = new StandardDonutGenerator(container, font, emSize, parameters, stroke);
            var donuts         = donutGenerator.Generate();

            var symbols = GenerateAtomSymbols(container, symbolRemap,
                                              visibility, parameters,
                                              annotations, foreground,
                                              stroke, donutGenerator);
            var bondElements = StandardBondGenerator.GenerateBonds(container, symbols,
                                                                   parameters, stroke,
                                                                   font, emSize, annotations,
                                                                   donutGenerator);

            var style     = parameters.GetHighlighting();
            var glowWidth = parameters.GetOuterGlowWidth();

            var backLayer   = new ElementGroup();
            var middleLayer = new ElementGroup();
            var frontLayer  = new ElementGroup();

            // bond elements can simply be added to the element group
            for (int i = 0; i < container.Bonds.Count; i++)
            {
                var bond = container.Bonds[i];

                if (IsHidden(bond))
                {
                    continue;
                }

                var highlight = GetHighlightColor(bond, parameters);
                if (highlight != null && style == HighlightStyle.OuterGlow)
                {
                    backLayer.Add(MarkedElement.Markup(OuterGlow(bondElements[i], highlight.Value, glowWidth, stroke), "outerglow"));
                }
                if (highlight != null && style == HighlightStyle.Colored)
                {
                    frontLayer.Add(MarkedElement.MarkupBond(Recolor(bondElements[i], highlight.Value), bond));
                }
                else
                {
                    middleLayer.Add(MarkedElement.MarkupBond(bondElements[i], bond));
                }
            }

            // bonds for delocalised aromatic
            frontLayer.Add(donuts);

            // convert the atom symbols to IRenderingElements
            for (int i = 0; i < container.Atoms.Count; i++)
            {
                var atom = container.Atoms[i];

                if (IsHidden(atom))
                {
                    continue;
                }

                var highlight = GetHighlightColor(atom, parameters);
                var color     = GetColorOfAtom(symbolRemap, coloring, foreground, style, atom, highlight);

                if (symbols[i] == null)
                {
                    // we add a 'ball' around atoms with no symbols (e.g. carbons)
                    if (highlight != null && style == HighlightStyle.OuterGlow)
                    {
                        backLayer.Add(MarkedElement.Markup(new OvalElement(ToPoint(atom.Point2D.Value), 1.75 * glowWidth * stroke, true, highlight.Value), "outerglow"));
                    }
                    continue;
                }

                var symbolElements = new ElementGroup();
                foreach (var shape in symbols[i].GetOutlines())
                {
                    GeneralPath path = GeneralPath.ShapeOf(shape, color);
                    symbolElements.Add(path);
                }

                // add the annotations of the symbol to the annotations ElementGroup
                foreach (var shape in symbols[i].GetAnnotationOutlines())
                {
                    annotations.Add(MarkedElement.Markup(GeneralPath.ShapeOf(shape, annotationColor), "annotation"));
                }

                if (highlight != null && style == HighlightStyle.OuterGlow)
                {
                    backLayer.Add(MarkedElement.Markup(OuterGlow(symbolElements, highlight.Value, glowWidth, stroke), "outerglow"));
                }

                if (highlight != null && style == HighlightStyle.Colored)
                {
                    frontLayer.Add(MarkedElement.MarkupAtom(symbolElements, atom));
                }
                else
                {
                    middleLayer.Add(MarkedElement.MarkupAtom(symbolElements, atom));
                }
            }

            // Add the Sgroups display elements to the front layer
            var sgroups = StandardSgroupGenerator.Generate(parameters, stroke, font, emSize, foreground, atomGenerator, symbols, container);

            frontLayer.Add(sgroups);

            // Annotations are added to the front layer.
            frontLayer.Add(annotations);

            var group = new ElementGroup
            {
                backLayer,
                middleLayer,
                frontLayer
            };

            return(MarkedElement.MarkupMol(group, container));
        }
예제 #4
0
        /// <summary>
        /// Depict a reaction.
        /// </summary>
        /// <param name="rxn">reaction instance</param>
        /// <returns>depiction</returns>
        /// <exception cref="CDKException">a depiction could not be generated</exception>
        public Depiction Depict(IReaction rxn, IReadOnlyDictionary <IChemObject, Color> highlight = null)
        {
            if (highlight == null)
            {
                highlight = Dictionaries.Empty <IChemObject, Color>();
            }

            Ensure2DLayout(rxn); // can reorder components!

            var fgcol = templateModel.GetAtomColorer().GetAtomColor(rxn.Builder.NewAtom("C"));

            var reactants = rxn.Reactants.ToList();
            var products  = rxn.Products.ToList();
            var agents    = rxn.Agents.ToList();
            List <LayoutBackup> layoutBackups = new List <LayoutBackup>();

            // set ids for tagging elements
            int molId = 0;

            foreach (var mol in reactants)
            {
                SetIfMissing(mol, MarkedElement.IdKey, "mol" + ++molId);
                SetIfMissing(mol, MarkedElement.ClassKey, "reactant");
                layoutBackups.Add(new LayoutBackup(mol));
            }
            foreach (var mol in products)
            {
                SetIfMissing(mol, MarkedElement.IdKey, "mol" + ++molId);
                SetIfMissing(mol, MarkedElement.ClassKey, "product");
                layoutBackups.Add(new LayoutBackup(mol));
            }
            foreach (var mol in agents)
            {
                SetIfMissing(mol, MarkedElement.IdKey, "mol" + ++molId);
                SetIfMissing(mol, MarkedElement.ClassKey, "agent");
                layoutBackups.Add(new LayoutBackup(mol));
            }

            var myHighlight = new Dictionary <IChemObject, Color>();

            if (atomMapColors != null)
            {
                foreach (var e in MakeHighlightAtomMap(reactants, products))
                {
                    myHighlight[e.Key] = e.Value;
                }
            }
            // user highlight buffer pushes out the atom-map highlight if provided
            foreach (var e in highlight)
            {
                myHighlight[e.Key] = e.Value;
            }

            PrepareCoords(reactants);
            PrepareCoords(products);
            PrepareCoords(agents);

            // highlight parts
            foreach (var e in myHighlight)
            {
                e.Key.SetProperty(StandardGenerator.HighlightColorKey, e.Value);
            }

            // setup the model scale based on bond length
            var scale = this.CaclModelScale(rxn);
            var model = CreateModel();

            model.SetScale(scale);

            // reactant/product/agent element generation, we number the reactants, then products then agents
            var reactantBounds = Generate(reactants, model, 1);
            var productBounds  = Generate(rxn.Products.ToList(), model, rxn.Reactants.Count);
            var agentBounds    = Generate(rxn.Agents.ToList(), model, rxn.Reactants.Count + rxn.Products.Count);

            // remove current highlight buffer
            foreach (var obj in myHighlight.Keys)
            {
                obj.RemoveProperty(StandardGenerator.HighlightColorKey);
            }

            // generate a 'plus' element
            var plus = GeneratePlusSymbol(scale, fgcol);

            // reset the coordinates to how they were before we invoked depict
            foreach (LayoutBackup backup in layoutBackups)
            {
                backup.Reset();
            }

            var emptyBounds    = new Bounds();
            var title          = model.GetShowReactionTitle() ? GenerateTitle(model, rxn, scale) : emptyBounds;
            var reactantTitles = new List <Bounds>();
            var productTitles  = new List <Bounds>();

            if (model.GetShowMoleculeTitle())
            {
                foreach (IAtomContainer reactant in reactants)
                {
                    reactantTitles.Add(GenerateTitle(model, reactant, scale));
                }
                foreach (IAtomContainer product in products)
                {
                    productTitles.Add(GenerateTitle(model, product, scale));
                }
            }

            Bounds conditions = GenerateReactionConditions(rxn, fgcol, model.GetScale());

            return(new ReactionDepiction(model,
                                         reactantBounds, productBounds, agentBounds,
                                         plus, rxn.Direction, dimensions,
                                         reactantTitles,
                                         productTitles,
                                         title,
                                         conditions,
                                         fgcol));
        }