private IRenderingElement GenerateAbbreviationSgroup(IAtomContainer mol, Sgroup sgroup) { string label = sgroup.Subscript; // already handled by symbol remapping if (sgroup.Bonds.Count > 0 || string.IsNullOrEmpty(label)) { return(new ElementGroup()); } if (!CheckAbbreviationHighlight(mol, sgroup)) { return(new ElementGroup()); } // we're showing a label where there were no atoms before, we put it in the // middle of all of those which were hidden var sgroupAtoms = sgroup.Atoms; Debug.Assert(sgroupAtoms.Any()); var highlight = sgroupAtoms.First().GetProperty <Color>(StandardGenerator.HighlightColorKey); var style = parameters.GetHighlighting(); var glowWidth = parameters.GetOuterGlowWidth(); Vector2 labelCoords = GeometryUtil.Get2DCenter(sgroupAtoms); ElementGroup labelgroup = new ElementGroup(); foreach (var outline in atomGenerator.GenerateAbbreviatedSymbol(label, HydrogenPosition.Right) .Resize(1 / scale, 1 / -scale) .GetOutlines()) { if (highlight != null && style == HighlightStyle.Colored) { labelgroup.Add(GeneralPath.ShapeOf(outline, highlight)); } else { labelgroup.Add(GeneralPath.ShapeOf(outline, foreground)); } } if (highlight != null && style == HighlightStyle.OuterGlow) { ElementGroup group = new ElementGroup { // outer glow needs to be being the label StandardGenerator.OuterGlow(labelgroup, highlight, glowWidth, stroke), labelgroup }; return(group); } else { return(MarkedElement.MarkupAtom(labelgroup, null)); } }
/// <inheritdoc/> public virtual IRenderingElement Generate(IAtomContainer container, RendererModel model) { ElementGroup elementGroup = new ElementGroup(); foreach (var atom in container.Atoms) { elementGroup.Add(MarkedElement.MarkupAtom(this.Generate(container, atom, model), atom)); } return(elementGroup); }
private IRenderingElement GenerateAbbreviationSgroup(IAtomContainer mol, Sgroup sgroup) { string label = sgroup.Subscript; // already handled by symbol remapping if (sgroup.Bonds.Count > 0 || string.IsNullOrEmpty(label)) { return(new ElementGroup()); } if (!CheckAbbreviationHighlight(mol, sgroup)) { return(new ElementGroup()); } // we're showing a label where there were no atoms before, we put it in the // middle of all of those which were hidden var sgroupAtoms = sgroup.Atoms; Debug.Assert(sgroupAtoms.Any()); var highlight = sgroupAtoms.First().GetProperty <Color>(StandardGenerator.HighlightColorKey); var style = parameters.GetHighlighting(); var glowWidth = parameters.GetOuterGlowWidth(); Vector2 labelLocation; if (mol.Atoms.Count == sgroup.Atoms.Count) { labelLocation = GeometryUtil.Get2DCenter(sgroupAtoms); } else { // contraction of part of a fragment, e.g. SALT // here we work out the point we want to place the contract relative // to the SGroup Atoms labelLocation = new Vector2(); var sgrpCenter = GeometryUtil.Get2DCenter(sgroupAtoms); var molCenter = GeometryUtil.Get2DCenter(mol); var minMax = GeometryUtil.GetMinMax(sgroupAtoms); var xDiff = sgrpCenter.X - molCenter.X; var yDiff = sgrpCenter.Y - molCenter.Y; if (xDiff > 0.1) { labelLocation.X = minMax[0]; // min x label = INTERPUNCT + label; } else if (xDiff < -0.1) { labelLocation.X = minMax[2]; // max x label = label + INTERPUNCT; } else { labelLocation.X = sgrpCenter.X; label = INTERPUNCT + label; } if (yDiff > 0.1) { labelLocation.Y = minMax[1]; // min y } else if (yDiff < -0.1) { labelLocation.Y = minMax[3]; // max y } else { labelLocation.Y = sgrpCenter.Y; } } var labelgroup = new ElementGroup(); foreach (var outline in atomGenerator.GenerateAbbreviatedSymbol(label, HydrogenPosition.Right) .Center(labelLocation.X, labelLocation.Y) .Resize(1 / scale, 1 / -scale) .GetOutlines()) { if (highlight != null && style == HighlightStyle.Colored) { labelgroup.Add(GeneralPath.ShapeOf(outline, highlight)); } else { labelgroup.Add(GeneralPath.ShapeOf(outline, foreground)); } } if (highlight != null && style == HighlightStyle.OuterGlow) { var group = new ElementGroup { // outer glow needs to be being the label StandardGenerator.OuterGlow(labelgroup, highlight, glowWidth, stroke), labelgroup }; return(group); } else { return(MarkedElement.MarkupAtom(labelgroup, null)); } }
/// <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)); }