public FunctionalGroupTextSource(FunctionalGroup parentGroup, bool isFlipped = false) { foreach (var term in parentGroup.ExpandIntoTerms(isFlipped)) { foreach (var part in term.Parts) { Runs.Add(new LabelTextSourceRun { IsAnchor = term.IsAnchor, IsEndParagraph = false, IsSubscript = part.Type == FunctionalGroupPartType.Subscript, IsSuperscript = part.Type == FunctionalGroupPartType.Superscript, Text = part.Text }); } } }
public void CreateFunctionalGroupCharacters(Atom atom, Options options) { FunctionalGroup fg = atom.Element as FunctionalGroup; double baFromNorth = Vector.AngleBetween(BasicGeometry.ScreenNorth, atom.BalancingVector(true)); CompassPoints nesw = BasicGeometry.SnapTo2EW(baFromNorth); bool reverse = nesw == CompassPoints.West; #region Set Up Atom Colours string atomColour = "000000"; if (options.ColouredAtoms) { if (!string.IsNullOrEmpty(fg.Colour)) { atomColour = fg.Colour; // Strip out # as OoXml does not use it atomColour = atomColour.Replace("#", ""); } } #endregion Set Up Atom Colours List <FunctionalGroupTerm> terms = fg.ExpandIntoTerms(reverse); #region Step 1 - Generate the characters and measure Bounding Boxes var cursorPosition = atom.Position; List <AtomLabelCharacter> fgCharacters = new List <AtomLabelCharacter>(); TtfCharacter hydrogenCharacter = _TtfCharacterSet['H']; Rect fgBoundingBox = Rect.Empty; Rect anchorBoundingBox = Rect.Empty; foreach (var term in terms) { foreach (var part in term.Parts) { foreach (char c in part.Text) { Rect bb = AddCharacter(c, part.Type); fgBoundingBox.Union(bb); if (term.IsAnchor) { anchorBoundingBox.Union(bb); } } } } #endregion Step 1 - Generate the characters and measure Bounding Boxes #region Step 2 - Move all characters such that the anchor term is centered on the atom position double offsetX; double offsetY; if (reverse) { offsetX = fgBoundingBox.Width - anchorBoundingBox.Width / 2; offsetY = anchorBoundingBox.Height / 2; } else { offsetX = anchorBoundingBox.Width / 2; offsetY = anchorBoundingBox.Height / 2; } offsetY = offsetY + anchorBoundingBox.Top - atom.Position.Y; foreach (var alc in fgCharacters) { alc.Position = new Point(alc.Position.X - offsetX, alc.Position.Y - offsetY); } #endregion Step 2 - Move all characters such that the anchor term is centered on the atom position #region Step 3 - Transfer characters into main list foreach (var alc in fgCharacters) { _AtomLabelCharacters.Add(alc); } #endregion Step 3 - Transfer characters into main list #region Step 4 - Convex Hull _convexhHulls.Add(atom.Path, ConvexHull(atom.Path)); #endregion Step 4 - Convex Hull // Local Function Rect AddCharacter(char c, FunctionalGroupPartType type) { TtfCharacter ttf = _TtfCharacterSet[c]; var thisCharacterPosition = GetCharacterPosition(cursorPosition, ttf); var alc = new AtomLabelCharacter(thisCharacterPosition, ttf, atomColour, c, atom.Path, atom.Parent.Path); alc.IsSubScript = type == FunctionalGroupPartType.Subscript; alc.IsSuperScript = type == FunctionalGroupPartType.Superscript; alc.IsSmaller = alc.IsSubScript || alc.IsSuperScript; Rect thisBoundingBox; if (alc.IsSmaller) { // Start by assuming it's SubScript thisCharacterPosition.Offset(0, OoXmlHelper.ScaleCsTtfToCml(hydrogenCharacter.Height * OoXmlHelper.SUBSCRIPT_DROP_FACTOR, _meanBondLength)); if (alc.IsSuperScript) { // Shift up by height of H to make it SuperScript thisCharacterPosition.Offset(0, -OoXmlHelper.ScaleCsTtfToCml(hydrogenCharacter.Height, _meanBondLength)); } // Reset the character's position alc.Position = thisCharacterPosition; thisBoundingBox = new Rect(alc.Position, new Size(OoXmlHelper.ScaleCsTtfToCml(alc.Character.Width, _meanBondLength) * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR, OoXmlHelper.ScaleCsTtfToCml(alc.Character.Height, _meanBondLength) * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR)); cursorPosition.Offset(OoXmlHelper.ScaleCsTtfToCml(alc.Character.IncrementX, _meanBondLength) * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR, 0); } else { thisBoundingBox = new Rect(alc.Position, new Size(OoXmlHelper.ScaleCsTtfToCml(alc.Character.Width, _meanBondLength), OoXmlHelper.ScaleCsTtfToCml(alc.Character.Height, _meanBondLength))); cursorPosition.Offset(OoXmlHelper.ScaleCsTtfToCml(alc.Character.IncrementX, _meanBondLength), 0); } fgCharacters.Add(alc); return(thisBoundingBox); } }