private void ShrinkBondLinesPass2(Progress pb) { // so that they do not overlap label characters if (_atomLabelCharacters.Count > 1) { pb.Show(); } pb.Message = "Clipping Bond Lines - Pass 2"; pb.Value = 0; pb.Maximum = _atomLabelCharacters.Count; foreach (AtomLabelCharacter alc in _atomLabelCharacters) { pb.Increment(1); double width = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Width); double height = OoXmlHelper.ScaleCsTtfToCml(alc.Character.Height); if (alc.IsSubScript) { // Shrink bounding box width = width * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR; height = height * OoXmlHelper.SUBSCRIPT_SCALE_FACTOR; } // Create rectangle of the bounding box with a suitable clipping margin Rect cbb = new Rect(alc.Position.X - OoXmlHelper.CHARACTER_CLIPPING_MARGIN, alc.Position.Y - OoXmlHelper.CHARACTER_CLIPPING_MARGIN, width + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2), height + (OoXmlHelper.CHARACTER_CLIPPING_MARGIN * 2)); //Debug.WriteLine("Character: " + alc.Ascii + " Rectangle: " + a); // Just in case we end up splitting a line into two List <BondLine> extraBondLines = new List <BondLine>(); // Select Lines which may require trimming // By using LINQ to implement the following SQL // Where (L.Right Between Cbb.Left And Cbb.Right) // Or (L.Left Between Cbb.Left And Cbb.Right) // Or (L.Top Between Cbb.Top And Cbb.Botton) // Or (L.Bottom Between Cbb.Top And Cbb.Botton) var targeted = from l in _bondLines where (cbb.Left <= l.BoundingBox.Right & l.BoundingBox.Right <= cbb.Right) | (cbb.Left <= l.BoundingBox.Left & l.BoundingBox.Left <= cbb.Right) | (cbb.Top <= l.BoundingBox.Top & l.BoundingBox.Top <= cbb.Bottom) | (cbb.Top <= l.BoundingBox.Bottom & l.BoundingBox.Bottom <= cbb.Bottom) select l; foreach (BondLine bl in targeted) { //pb.Increment(1); Point start = new Point(bl.Start.X, bl.Start.Y); Point end = new Point(bl.End.X, bl.End.Y); //Debug.WriteLine(" Line From: " + start + " To: " + end); int attempts = 0; if (CohenSutherland.ClipLine(cbb, ref start, ref end, out attempts)) { //Debug.WriteLine(" Clipped Line Start Point: " + start); //Debug.WriteLine(" Clipped Line End Point: " + end); bool bClipped = false; if (Math.Abs(bl.Start.X - start.X) < EPSILON && Math.Abs(bl.Start.Y - start.Y) < EPSILON) { bl.Start = new Point(end.X, end.Y); bClipped = true; } if (Math.Abs(bl.End.X - end.X) < EPSILON && Math.Abs(bl.End.Y - end.Y) < EPSILON) { bl.End = new Point(start.X, start.Y); bClipped = true; } if (!bClipped) { // Line was clipped at both ends; // 1. Generate new line BondLine extraLine = new BondLine(new Point(end.X, end.Y), new Point(bl.End.X, bl.End.Y), bl.Type, bl.ParentBond, bl.ParentMolecule, bl.StartAtomId, bl.EndAtomId); extraBondLines.Add(extraLine); // 2. Trim existing line bl.End = new Point(start.X, start.Y); } } if (attempts >= 15) { Debug.WriteLine("Clipping failed !"); } } // Add any extra lines generated by this character into the List of Bond Lines foreach (BondLine bl in extraBondLines) { _bondLines.Add(bl); } } }