//draws the isotope label at ten-o-clock private LabelMetrics DrawIsotopeLabel(DrawingContext drawingContext, AtomTextMetrics mainAtomMetrics, AtomTextMetrics hMetrics) { Debug.Assert(Isotope != null); string isoLabel = Isotope.ToString(); var isotopeText = new IsotopeLabelText(isoLabel, PixelsPerDip()); Vector isotopeOffsetVector = BasicGeometry.ScreenNorth * GlyphText.SymbolSize; Matrix rotator = new Matrix(); double angle = -60; //avoid overlap of label and hydrogens if (hMetrics != null && ParentAtom.GetDefaultHOrientation() == CompassPoints.West) { angle = -35; } rotator.Rotate(angle); isotopeOffsetVector = isotopeOffsetVector * rotator; Point isoCenter = mainAtomMetrics.Geocenter + isotopeOffsetVector; isotopeText.MeasureAtCenter(isoCenter); isotopeText.Fill = Fill; isotopeText.DrawAtBottomLeft(isotopeText.TextMetrics.BoundingBox.BottomLeft, drawingContext); return(isotopeText.TextMetrics); }
private void RenderAtom(DrawingContext drawingContext) { //renders the atom complete with charges, hydrogens and labels. //this code is *complex* - alter it at your own risk! List <Point> symbolPoints = new List <Point>(); List <Point> hydrogenPoints = new List <Point>(); //private variables used to keep track of onscreen visuals AtomTextMetrics hydrogenMetrics = null; LabelMetrics isoMetrics = null; SubscriptedGroup subscriptedGroup = null; Hull = new List <Point>(); //stage 1: measure up the main atom symbol in position //we need the metrics first if (AtomSymbol != "") { var symbolText = new GlyphText(AtomSymbol, SymbolTypeface, GlyphText.SymbolSize, PixelsPerDip()); symbolText.MeasureAtCenter(Position); //grab the hull for later if (symbolText.FlattenedPath != null) { Hull.AddRange(symbolText.FlattenedPath); } } //stage 2. grab the main atom metrics br drawing it var mainAtomMetrics = DrawSelf(drawingContext); //if it's a vertex atom we need the hull if (AtomSymbol == "") { Hull.AddRange(mainAtomMetrics.FlattenedPath); } //stage 3: measure up the hydrogens //if we have implicit hydrogens and we have an explicit label, draw them if (ImplicitHydrogenCount > 0 && AtomSymbol != "") { var defaultHOrientation = ParentAtom.GetDefaultHOrientation(); subscriptedGroup = new SubscriptedGroup(ImplicitHydrogenCount, "H", GlyphText.SymbolSize); hydrogenMetrics = subscriptedGroup.Measure(mainAtomMetrics, defaultHOrientation, PixelsPerDip()); subscriptedGroup.DrawSelf(drawingContext, hydrogenMetrics, PixelsPerDip(), Fill); hydrogenPoints = hydrogenMetrics.FlattenedPath; Hull.AddRange(hydrogenPoints); } //stage 6: draw an isotope label if needed if (Isotope != null) { isoMetrics = DrawIsotopeLabel(drawingContext, mainAtomMetrics, hydrogenMetrics); Hull.AddRange(isoMetrics.Corners); } //stage7: draw any charges if ((Charge ?? 0) != 0) { LabelMetrics cMetrics = DrawCharges(drawingContext, mainAtomMetrics, hydrogenMetrics, isoMetrics, ParentAtom.GetDefaultHOrientation()); Hull.AddRange(cMetrics.FlattenedPath); } //stage 8: recalculate the hull if (Hull.Any()) { //sort the points properly before doing a hull calculation var sortedHull = (from Point p in Hull orderby p.X, p.Y descending select p).ToList(); Hull = Geometry <Point> .GetHull(sortedHull, p => p); // Diag: Show the Hull #if DEBUG #if SHOWHULLS ShowHull(Hull, drawingContext); #endif #endif // End Diag } // Diag: Show the Atom Point #if DEBUG #if SHOWATOMCENTRES drawingContext.DrawEllipse(Brushes.Red, null, ParentAtom.Position, 5, 5); #endif #endif // End Diag }